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. Should be
109// converted to consteval when get to C++20.
110template <int M, int N>
111constexpr auto
113{
115
116 for (ErrorInfo const& info : unordered)
117 {
118 if (info.code <= RpcSuccess || info.code > RpcLast)
119 throw(std::out_of_range("Invalid error_code_i"));
120
121 // The first valid code follows rpcSUCCESS immediately.
122 static_assert(RpcSuccess == 0, "Unexpected error_code_i layout.");
123 int const index{info.code - 1};
124
125 if (ret[index].code != RpcUnknown)
126 throw(std::invalid_argument("Duplicate error_code_i in list"));
127
128 ret[index] = info;
129 }
130
131 // Verify that all entries are filled in starting with 1 and proceeding
132 // to rpcLAST.
133 //
134 // It's okay for there to be missing entries; they will contain the code
135 // rpcUNKNOWN. But other than that all entries should match their index.
136 int codeCount{0};
137 int expect{RpcBadSyntax - 1};
138 for (ErrorInfo const& info : ret)
139 {
140 ++expect;
141 if (info.code == RpcUnknown)
142 continue;
143
144 if (info.code != expect)
145 throw(std::invalid_argument("Empty error_code_i in list"));
146 ++codeCount;
147 }
148 if (expect != RpcLast)
149 throw(std::invalid_argument("Insufficient list entries"));
150 if (codeCount != N)
151 throw(std::invalid_argument("Bad handling of unorderedErrorInfos"));
152
153 return ret;
154}
155
157
159
160} // namespace detail
161
162//------------------------------------------------------------------------------
163
164void
166{
167 ErrorInfo const& info(getErrorInfo(code));
168 json[jss::error] = info.token;
169 json[jss::error_code] = info.code;
170 json[jss::error_message] = info.message;
171}
172
173void
175{
176 ErrorInfo const& info(getErrorInfo(code));
177 json[jss::error] = info.token;
178 json[jss::error_code] = info.code;
179 json[jss::error_message] = message;
180}
181
182ErrorInfo const&
184{
185 if (code <= RpcSuccess || code > RpcLast)
187 return detail::kSortedErrorInfos[code - 1];
188}
189
192{
194 injectError(code, json);
195 return json;
196}
197
199makeError(ErrorCodeI code, std::string const& message)
200{
202 injectError(code, message, json);
203 return json;
204}
205
206bool
208{
209 return json.isObject() && json.isMember(jss::error);
210}
211
212int
214{
215 return getErrorInfo(code).httpStatus;
216}
217
218} // namespace RPC
219
222{
223 XRPL_ASSERT(RPC::containsError(jv), "xrpl::RPC::rpcErrorString : input contains an error");
224 return jv[jss::error].asString() + jv[jss::error_message].asString();
225}
226
227} // namespace xrpl
Represents a JSON value.
Definition json_value.h:130
std::string asString() const
Returns the unquoted string value.
JSON (JavaScript Object Notation).
Definition json_errors.h:5
constexpr ErrorInfo kUnknownError
constexpr auto sortErrorInfos(ErrorInfo const (&unordered)[N]) -> std::array< ErrorInfo, M >
static constexpr ErrorInfo kUnorderedErrorInfos[]
constexpr auto kSortedErrorInfos
API version numbers used in later API versions.
Definition ApiVersion.h:35
json::Value makeError(ErrorCodeI code)
Returns a new json object that reflects the error code.
int errorCodeHttpStatus(ErrorCodeI code)
Returns http status that corresponds to the error code.
ErrorInfo const & getErrorInfo(ErrorCodeI code)
Returns an ErrorInfo that reflects the error code.
void injectError(ErrorCodeI code, json::Value &json)
Add or update the json update to reflect the error code.
bool containsError(json::Value const &json)
Returns true if the json contains an rpc error specification.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
ErrorCodeI
Definition ErrorCodes.h:22
@ RpcDstAmtMalformed
Definition ErrorCodes.h:88
@ RpcDstActNotFound
Definition ErrorCodes.h:87
@ RpcBadSecret
Definition ErrorCodes.h:80
@ RpcBadCredentials
Definition ErrorCodes.h:134
@ RpcChannelAmtMalformed
Definition ErrorCodes.h:83
@ RpcNoClosed
Definition ErrorCodes.h:46
@ RpcInvalidHotwallet
Definition ErrorCodes.h:63
@ RpcBadFeature
Definition ErrorCodes.h:77
@ RpcOracleMalformed
Definition ErrorCodes.h:131
@ RpcInternal
Definition ErrorCodes.h:112
@ RpcBadIssuer
Definition ErrorCodes.h:78
@ RpcStreamMalformed
Definition ErrorCodes.h:108
@ RpcDelegateActNotFound
Definition ErrorCodes.h:105
@ RpcLast
Definition ErrorCodes.h:146
@ RpcSrcActMalformed
Definition ErrorCodes.h:102
@ RpcNotImpl
Definition ErrorCodes.h:113
@ RpcNotSupported
Definition ErrorCodes.h:114
@ RpcAlreadySingleSig
Definition ErrorCodes.h:74
@ RpcNoNetwork
Definition ErrorCodes.h:48
@ RpcSigningMalformed
Definition ErrorCodes.h:100
@ RpcLgrNotFound
Definition ErrorCodes.h:54
@ RpcObjectNotFound
Definition ErrorCodes.h:125
@ RpcNoPfRequest
Definition ErrorCodes.h:68
@ RpcActNotFound
Definition ErrorCodes.h:52
@ RpcBadMarket
Definition ErrorCodes.h:79
@ RpcEntryNotFound
Definition ErrorCodes.h:143
@ RpcAmendmentBlocked
Definition ErrorCodes.h:43
@ RpcBadKeyType
Definition ErrorCodes.h:115
@ RpcSuccess
Definition ErrorCodes.h:26
@ RpcUnknown
Definition ErrorCodes.h:24
@ RpcExpiredValidatorList
Definition ErrorCodes.h:119
@ RpcActMalformed
Definition ErrorCodes.h:72
@ RpcNotSynced
Definition ErrorCodes.h:49
@ RpcHighFee
Definition ErrorCodes.h:40
@ RpcExcessiveLgrRange
Definition ErrorCodes.h:117
@ RpcMasterDisabled
Definition ErrorCodes.h:56
@ RpcDstActMalformed
Definition ErrorCodes.h:85
@ RpcTxnNotFound
Definition ErrorCodes.h:62
@ RpcNotReady
Definition ErrorCodes.h:42
@ RpcLgrIdxsInvalid
Definition ErrorCodes.h:94
@ RpcDomainMalformed
Definition ErrorCodes.h:140
@ RpcPublicMalformed
Definition ErrorCodes.h:99
@ RpcCommandMissing
Definition ErrorCodes.h:84
@ RpcSlowDown
Definition ErrorCodes.h:39
@ RpcJsonRpc
Definition ErrorCodes.h:29
@ RpcAtxDeprecated
Definition ErrorCodes.h:109
@ RpcSrcActMissing
Definition ErrorCodes.h:103
@ RpcDstActMissing
Definition ErrorCodes.h:86
@ RpcSrcCurMalformed
Definition ErrorCodes.h:106
@ RpcNoEvents
Definition ErrorCodes.h:36
@ RpcUnexpectedLedgerType
Definition ErrorCodes.h:144
@ RpcDstAmtMissing
Definition ErrorCodes.h:89
@ RpcIssueMalformed
Definition ErrorCodes.h:128
@ RpcNotEnabled
Definition ErrorCodes.h:41
@ RpcInvalidParams
Definition ErrorCodes.h:66
@ RpcLgrNotValidated
Definition ErrorCodes.h:55
@ RpcSendmaxMalformed
Definition ErrorCodes.h:101
@ RpcBadSeed
Definition ErrorCodes.h:81
@ RpcSrcIsrMalformed
Definition ErrorCodes.h:107
@ RpcBadSyntax
Definition ErrorCodes.h:28
@ RpcWrongNetwork
Definition ErrorCodes.h:32
@ RpcTooBusy
Definition ErrorCodes.h:38
@ RpcDbDeserialization
Definition ErrorCodes.h:116
@ RpcChannelMalformed
Definition ErrorCodes.h:82
@ RpcDstIsrMalformed
Definition ErrorCodes.h:90
@ RpcNoPermission
Definition ErrorCodes.h:35
@ RpcForbidden
Definition ErrorCodes.h:30
@ RpcInvalidLgrRange
Definition ErrorCodes.h:118
@ RpcLgrIdxMalformed
Definition ErrorCodes.h:95
@ RpcUnknownCommand
Definition ErrorCodes.h:67
@ RpcTxSigned
Definition ErrorCodes.h:137
@ RpcAlreadyMultisig
Definition ErrorCodes.h:73
@ RpcNoCurrent
Definition ErrorCodes.h:47
@ RpcSrcActNotFound
Definition ErrorCodes.h:104
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:172
json::StaticString token
Definition ErrorCodes.h:190
json::StaticString message
Definition ErrorCodes.h:191