xrpld
Loading...
Searching...
No Matches
ErrorCodes.cpp
1#include <xrpl/protocol/ErrorCodes.h>
2
3#include <xrpl/beast/utility/instrumentation.h>
4#include <xrpl/json/json_value.h>
5#include <xrpl/protocol/jss.h>
6
7#include <array>
8#include <stdexcept>
9#include <string>
10
11namespace xrpl {
12namespace rpc {
13
14namespace detail {
15
16// Unordered array of ErrorInfos, so we don't have to maintain the list
17// ordering by hand.
18//
19// This array will be omitted from the object file; only the sorted version
20// will remain in the object file. But the string literals will remain.
21//
22// There's a certain amount of tension in determining the correct HTTP
23// status to associate with a given RPC error. Initially all RPC errors
24// returned 200 (OK). And that's the default behavior if no HTTP status code
25// is specified below.
26//
27// The codes currently selected target the load balancer fail-over use case.
28// If a query fails on one node but is likely to have a positive outcome
29// on a different node, then the failure should return a 4xx/5xx range
30// status code.
31
32// clang-format off
34 {RpcActMalformed, "actMalformed", "Account malformed."},
35 {RpcActNotFound, "actNotFound", "Account not found."},
36 {RpcAlreadyMultisig, "alreadyMultisig", "Already multisigned."},
37 {RpcAlreadySingleSig, "alreadySingleSig", "Already single-signed."},
38 {RpcAmendmentBlocked, "amendmentBlocked", "Amendment blocked, need upgrade.", 503},
39 {RpcExpiredValidatorList, "unlBlocked", "Validator list expired.", 503},
40 {RpcAtxDeprecated, "deprecated", "Use the new API or specify a ledger range.", 400},
41 {RpcBadKeyType, "badKeyType", "Bad key type.", 400},
42 {RpcBadFeature, "badFeature", "Feature unknown or invalid.", 500},
43 {RpcBadIssuer, "badIssuer", "Issuer account malformed.", 400},
44 {RpcBadMarket, "badMarket", "No such market.", 404},
45 {RpcBadSecret, "badSecret", "Secret does not match account.", 403},
46 {RpcBadSeed, "badSeed", "Disallowed seed.", 403},
47 {RpcBadSyntax, "badSyntax", "Syntax error.", 400},
48 {RpcChannelMalformed, "channelMalformed", "Payment channel is malformed.", 400},
49 {RpcChannelAmtMalformed, "channelAmtMalformed", "Payment channel amount is malformed.", 400},
50 {RpcCommandMissing, "commandMissing", "Missing command entry.", 400},
51 {RpcDbDeserialization, "dbDeserialization", "Database deserialization error.", 502},
52 {RpcDstActMalformed, "dstActMalformed", "Destination account is malformed.", 400},
53 {RpcDstActMissing, "dstActMissing", "Destination account not provided.", 400},
54 {RpcDstActNotFound, "dstActNotFound", "Destination account not found.", 404},
55 {RpcDstAmtMalformed, "dstAmtMalformed", "Destination amount/currency/issuer is malformed.", 400},
56 {RpcDstAmtMissing, "dstAmtMissing", "Destination amount/currency/issuer is missing.", 400},
57 {RpcDstIsrMalformed, "dstIsrMalformed", "Destination issuer is malformed.", 400},
58 {RpcExcessiveLgrRange, "excessiveLgrRange", "Ledger range exceeds 1000.", 400},
59 {RpcForbidden, "forbidden", "Bad credentials.", 403},
60 {RpcHighFee, "highFee", "Current transaction fee exceeds your limit.", 402},
61 {RpcInternal, "internal", "Internal error.", 500},
62 {RpcInvalidLgrRange, "invalidLgrRange", "Ledger range is invalid.", 400},
63 {RpcInvalidParams, "invalidParams", "Invalid parameters.", 400},
64 {RpcInvalidHotwallet, "invalidHotWallet", "Invalid hotwallet.", 400},
65 {RpcIssueMalformed, "issueMalformed", "Issue is malformed.", 400},
66 {RpcJsonRpc, "json_rpc", "JSON-RPC transport error.", 500},
67 {RpcLgrIdxsInvalid, "lgrIdxsInvalid", "Ledger indexes invalid.", 400},
68 {RpcLgrIdxMalformed, "lgrIdxMalformed", "Ledger index malformed.", 400},
69 {RpcLgrNotFound, "lgrNotFound", "Ledger not found.", 404},
70 {RpcLgrNotValidated, "lgrNotValidated", "Ledger not validated.", 202},
71 {RpcMasterDisabled, "masterDisabled", "Master key is disabled.", 403},
72 {RpcNotEnabled, "notEnabled", "Not enabled in configuration.", 501},
73 {RpcNotImpl, "notImpl", "Not implemented.", 501},
74 {RpcNotReady, "notReady", "Not ready to handle this request.", 503},
75 {RpcNotSupported, "notSupported", "Operation not supported.", 501},
76 {RpcNoClosed, "noClosed", "Closed ledger is unavailable.", 503},
77 {RpcNoCurrent, "noCurrent", "Current ledger is unavailable.", 503},
78 {RpcNotSynced, "notSynced", "Not synced to the network.", 503},
79 {RpcNoEvents, "noEvents", "Current transport does not support events.", 405},
80 {RpcNoNetwork, "noNetwork", "Not synced to the network.", 503},
81 {RpcWrongNetwork, "wrongNetwork", "Wrong network.", 503},
82 {RpcNoPermission, "noPermission", "You don't have permission for this command.", 401},
83 {RpcNoPfRequest, "noPathRequest", "No pathfinding request in progress.", 404},
84 {RpcObjectNotFound, "objectNotFound", "The requested object was not found.", 404},
85 {RpcPublicMalformed, "publicMalformed", "Public key is malformed.", 400},
86 {RpcSendmaxMalformed, "sendMaxMalformed", "SendMax amount malformed.", 400},
87 {RpcSigningMalformed, "signingMalformed", "Signing of transaction is malformed.", 400},
88 {RpcSlowDown, "slowDown", "You are placing too much load on the server.", 429},
89 {RpcSrcActMalformed, "srcActMalformed", "Source account is malformed.", 400},
90 {RpcSrcActMissing, "srcActMissing", "Source account not provided.", 400},
91 {RpcSrcActNotFound, "srcActNotFound", "Source account not found.", 404},
92 {RpcDelegateActNotFound, "delegateActNotFound", "Delegate account not found.", 404},
93 {RpcSrcCurMalformed, "srcCurMalformed", "Source currency is malformed.", 400},
94 {RpcSrcIsrMalformed, "srcIsrMalformed", "Source issuer is malformed.", 400},
95 {RpcStreamMalformed, "malformedStream", "Stream malformed.", 400},
96 {RpcTooBusy, "tooBusy", "The server is too busy to help you now.", 503},
97 {RpcTxnNotFound, "txnNotFound", "Transaction not found.", 404},
98 {RpcUnknownCommand, "unknownCmd", "Unknown method.", 405},
99 {RpcOracleMalformed, "oracleMalformed", "Oracle request is malformed.", 400},
100 {RpcBadCredentials, "badCredentials", "Credentials do not exist, are not accepted, or have expired.", 400},
101 {RpcTxSigned, "transactionSigned", "Transaction should not be signed.", 400},
102 {RpcDomainMalformed, "domainMalformed", "Domain is malformed.", 400},
103 {RpcEntryNotFound, "entryNotFound", "Entry not found.", 400},
104 {RpcUnexpectedLedgerType, "unexpectedLedgerType", "Unexpected ledger type.", 400},
105};
106// clang-format on
107
108// Sort and validate unorderedErrorInfos at compile time.
109template <int M, int N>
110consteval auto
112{
114
115 for (ErrorInfo const& info : unordered)
116 {
117 if (info.code <= RpcSuccess || info.code > RpcLast)
118 throw(std::out_of_range("Invalid error_code_i"));
119
120 // The first valid code follows rpcSUCCESS immediately.
121 static_assert(RpcSuccess == 0, "Unexpected error_code_i layout.");
122 int const index{info.code - 1};
123
124 if (ret[index].code != RpcUnknown)
125 throw(std::invalid_argument("Duplicate error_code_i in list"));
126
127 ret[index] = info;
128 }
129
130 // Verify that all entries are filled in starting with 1 and proceeding
131 // to rpcLAST.
132 //
133 // It's okay for there to be missing entries; they will contain the code
134 // rpcUNKNOWN. But other than that all entries should match their index.
135 int codeCount{0};
136 int expect{RpcBadSyntax - 1};
137 for (ErrorInfo const& info : ret)
138 {
139 ++expect;
140 if (info.code == RpcUnknown)
141 continue;
142
143 if (info.code != expect)
144 throw(std::invalid_argument("Empty error_code_i in list"));
145 ++codeCount;
146 }
147 if (expect != RpcLast)
148 throw(std::invalid_argument("Insufficient list entries"));
149 if (codeCount != N)
150 throw(std::invalid_argument("Bad handling of unorderedErrorInfos"));
151
152 return ret;
153}
154
156
158
159} // namespace detail
160
161//------------------------------------------------------------------------------
162
163void
165{
166 ErrorInfo const& info(getErrorInfo(code));
167 json[jss::error] = info.token;
168 json[jss::error_code] = info.code;
169 json[jss::error_message] = info.message;
170}
171
172void
174{
175 ErrorInfo const& info(getErrorInfo(code));
176 json[jss::error] = info.token;
177 json[jss::error_code] = info.code;
178 json[jss::error_message] = message;
179}
180
181ErrorInfo const&
183{
184 if (code <= RpcSuccess || code > RpcLast)
186 return detail::kSortedErrorInfos[code - 1];
187}
188
191{
193 injectError(code, json);
194 return json;
195}
196
198makeError(ErrorCodeI code, std::string const& message)
199{
201 injectError(code, message, json);
202 return json;
203}
204
205bool
207{
208 return json.isObject() && json.isMember(jss::error);
209}
210
211int
213{
214 return getErrorInfo(code).httpStatus;
215}
216
217} // namespace rpc
218
221{
222 XRPL_ASSERT(rpc::containsError(jv), "xrpl::rpc::rpcErrorString : input contains an error");
223 return jv[jss::error].asString() + jv[jss::error_message].asString();
224}
225
226} // namespace xrpl
Represents a JSON value.
Definition json_value.h:117
std::string asString() const
Returns the unquoted string value.
JSON (JavaScript Object Notation).
Definition json_errors.h:5
static constexpr ErrorInfo kUnorderedErrorInfos[]
consteval auto sortErrorInfos(ErrorInfo const (&unordered)[N]) -> std::array< ErrorInfo, M >
constexpr auto kSortedErrorInfos
constexpr ErrorInfo kUnknownError
API version numbers used in later API versions.
Definition ApiVersion.h:36
bool containsError(json::Value const &json)
Returns true if the json contains an rpc error specification.
void injectError(ErrorCodeI code, json::Value &json)
Add or update the json update to reflect the error code.
int errorCodeHttpStatus(ErrorCodeI code)
Returns http status that corresponds to the error code.
json::Value makeError(ErrorCodeI code)
Returns a new json object that reflects the error code.
ErrorInfo const & getErrorInfo(ErrorCodeI code)
Returns an ErrorInfo that reflects the error code.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
ErrorCodeI
Definition ErrorCodes.h:23
@ RpcDstAmtMalformed
Definition ErrorCodes.h:89
@ RpcDstActNotFound
Definition ErrorCodes.h:88
@ RpcBadSecret
Definition ErrorCodes.h:81
@ RpcBadCredentials
Definition ErrorCodes.h:135
@ RpcChannelAmtMalformed
Definition ErrorCodes.h:84
@ RpcNoClosed
Definition ErrorCodes.h:47
@ RpcInvalidHotwallet
Definition ErrorCodes.h:64
@ RpcBadFeature
Definition ErrorCodes.h:78
@ RpcOracleMalformed
Definition ErrorCodes.h:132
@ RpcInternal
Definition ErrorCodes.h:113
@ RpcBadIssuer
Definition ErrorCodes.h:79
@ RpcStreamMalformed
Definition ErrorCodes.h:109
@ RpcDelegateActNotFound
Definition ErrorCodes.h:106
@ RpcLast
Definition ErrorCodes.h:147
@ RpcSrcActMalformed
Definition ErrorCodes.h:103
@ RpcNotImpl
Definition ErrorCodes.h:114
@ RpcNotSupported
Definition ErrorCodes.h:115
@ RpcAlreadySingleSig
Definition ErrorCodes.h:75
@ RpcNoNetwork
Definition ErrorCodes.h:49
@ RpcSigningMalformed
Definition ErrorCodes.h:101
@ RpcLgrNotFound
Definition ErrorCodes.h:55
@ RpcObjectNotFound
Definition ErrorCodes.h:126
@ RpcNoPfRequest
Definition ErrorCodes.h:69
@ RpcActNotFound
Definition ErrorCodes.h:53
@ RpcBadMarket
Definition ErrorCodes.h:80
@ RpcEntryNotFound
Definition ErrorCodes.h:144
@ RpcAmendmentBlocked
Definition ErrorCodes.h:44
@ RpcBadKeyType
Definition ErrorCodes.h:116
@ RpcSuccess
Definition ErrorCodes.h:27
@ RpcUnknown
Definition ErrorCodes.h:25
@ RpcExpiredValidatorList
Definition ErrorCodes.h:120
@ RpcActMalformed
Definition ErrorCodes.h:73
@ RpcNotSynced
Definition ErrorCodes.h:50
@ RpcHighFee
Definition ErrorCodes.h:41
@ RpcExcessiveLgrRange
Definition ErrorCodes.h:118
@ RpcMasterDisabled
Definition ErrorCodes.h:57
@ RpcDstActMalformed
Definition ErrorCodes.h:86
@ RpcTxnNotFound
Definition ErrorCodes.h:63
@ RpcNotReady
Definition ErrorCodes.h:43
@ RpcLgrIdxsInvalid
Definition ErrorCodes.h:95
@ RpcDomainMalformed
Definition ErrorCodes.h:141
@ RpcPublicMalformed
Definition ErrorCodes.h:100
@ RpcCommandMissing
Definition ErrorCodes.h:85
@ RpcSlowDown
Definition ErrorCodes.h:40
@ RpcJsonRpc
Definition ErrorCodes.h:30
@ RpcAtxDeprecated
Definition ErrorCodes.h:110
@ RpcSrcActMissing
Definition ErrorCodes.h:104
@ RpcDstActMissing
Definition ErrorCodes.h:87
@ RpcSrcCurMalformed
Definition ErrorCodes.h:107
@ RpcNoEvents
Definition ErrorCodes.h:37
@ RpcUnexpectedLedgerType
Definition ErrorCodes.h:145
@ RpcDstAmtMissing
Definition ErrorCodes.h:90
@ RpcIssueMalformed
Definition ErrorCodes.h:129
@ RpcNotEnabled
Definition ErrorCodes.h:42
@ RpcInvalidParams
Definition ErrorCodes.h:67
@ RpcLgrNotValidated
Definition ErrorCodes.h:56
@ RpcSendmaxMalformed
Definition ErrorCodes.h:102
@ RpcBadSeed
Definition ErrorCodes.h:82
@ RpcSrcIsrMalformed
Definition ErrorCodes.h:108
@ RpcBadSyntax
Definition ErrorCodes.h:29
@ RpcWrongNetwork
Definition ErrorCodes.h:33
@ RpcTooBusy
Definition ErrorCodes.h:39
@ RpcDbDeserialization
Definition ErrorCodes.h:117
@ RpcChannelMalformed
Definition ErrorCodes.h:83
@ RpcDstIsrMalformed
Definition ErrorCodes.h:91
@ RpcNoPermission
Definition ErrorCodes.h:36
@ RpcForbidden
Definition ErrorCodes.h:31
@ RpcInvalidLgrRange
Definition ErrorCodes.h:119
@ RpcLgrIdxMalformed
Definition ErrorCodes.h:96
@ RpcUnknownCommand
Definition ErrorCodes.h:68
@ RpcTxSigned
Definition ErrorCodes.h:138
@ RpcAlreadyMultisig
Definition ErrorCodes.h:74
@ RpcNoCurrent
Definition ErrorCodes.h:48
@ RpcSrcActNotFound
Definition ErrorCodes.h:105
std::string rpcErrorString(json::Value const &jv)
Returns a single string with the contents of an RPC error.
Maps an rpc error code to its token, default message, and HTTP status.
Definition ErrorCodes.h:176
json::StaticString message
Definition ErrorCodes.h:195
json::StaticString token
Definition ErrorCodes.h:194