rippled
ErrorCodes.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012 - 2019 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <ripple/protocol/ErrorCodes.h>
21 #include <array>
22 #include <cassert>
23 #include <stdexcept>
24 
25 namespace ripple {
26 namespace RPC {
27 
28 namespace detail {
29 
30 // Unordered array of ErrorInfos, so we don't have to maintain the list
31 // ordering by hand.
32 //
33 // This array will be omitted from the object file; only the sorted version
34 // will remain in the object file. But the string literals will remain.
35 //
36 // There's a certain amount of tension in determining the correct HTTP
37 // status to associate with a given RPC error. Initially all RPC errors
38 // returned 200 (OK). And that's the default behavior if no HTTP status code
39 // is specified below.
40 //
41 // The codes currently selected target the load balancer fail-over use case.
42 // If a query fails on one node but is likely to have a positive outcome
43 // on a different node, then the failure should return a 4xx/5xx range
44 // status code.
45 
46 // clang-format off
47 constexpr static ErrorInfo unorderedErrorInfos[]{
48  {rpcACT_MALFORMED, "actMalformed", "Account malformed."},
49  {rpcACT_NOT_FOUND, "actNotFound", "Account not found."},
50  {rpcALREADY_MULTISIG, "alreadyMultisig", "Already multisigned."},
51  {rpcALREADY_SINGLE_SIG, "alreadySingleSig", "Already single-signed."},
52  {rpcAMENDMENT_BLOCKED, "amendmentBlocked", "Amendment blocked, need upgrade.", 503},
53  {rpcEXPIRED_VALIDATOR_LIST, "unlBlocked", "Validator list expired.", 503},
54  {rpcATX_DEPRECATED, "deprecated", "Use the new API or specify a ledger range.", 400},
55  {rpcBAD_KEY_TYPE, "badKeyType", "Bad key type.", 400},
56  {rpcBAD_FEATURE, "badFeature", "Feature unknown or invalid.", 500},
57  {rpcBAD_ISSUER, "badIssuer", "Issuer account malformed.", 400},
58  {rpcBAD_MARKET, "badMarket", "No such market.", 404},
59  {rpcBAD_SECRET, "badSecret", "Secret does not match account.", 403},
60  {rpcBAD_SEED, "badSeed", "Disallowed seed.", 403},
61  {rpcBAD_SYNTAX, "badSyntax", "Syntax error.", 400},
62  {rpcCHANNEL_MALFORMED, "channelMalformed", "Payment channel is malformed.", 400},
63  {rpcCHANNEL_AMT_MALFORMED, "channelAmtMalformed", "Payment channel amount is malformed.", 400},
64  {rpcCOMMAND_MISSING, "commandMissing", "Missing command entry.", 400},
65  {rpcDB_DESERIALIZATION, "dbDeserialization", "Database deserialization error.", 502},
66  {rpcDST_ACT_MALFORMED, "dstActMalformed", "Destination account is malformed.", 400},
67  {rpcDST_ACT_MISSING, "dstActMissing", "Destination account not provided.", 400},
68  {rpcDST_ACT_NOT_FOUND, "dstActNotFound", "Destination account not found.", 404},
69  {rpcDST_AMT_MALFORMED, "dstAmtMalformed", "Destination amount/currency/issuer is malformed.", 400},
70  {rpcDST_AMT_MISSING, "dstAmtMissing", "Destination amount/currency/issuer is missing.", 400},
71  {rpcDST_ISR_MALFORMED, "dstIsrMalformed", "Destination issuer is malformed.", 400},
72  {rpcEXCESSIVE_LGR_RANGE, "excessiveLgrRange", "Ledger range exceeds 1000.", 400},
73  {rpcFORBIDDEN, "forbidden", "Bad credentials.", 403},
74  {rpcFAILED_TO_FORWARD, "failedToForward", "Failed to forward request to p2p node", 503},
75  {rpcHIGH_FEE, "highFee", "Current transaction fee exceeds your limit.", 402},
76  {rpcINTERNAL, "internal", "Internal error.", 500},
77  {rpcINVALID_LGR_RANGE, "invalidLgrRange", "Ledger range is invalid.", 400},
78  {rpcINVALID_PARAMS, "invalidParams", "Invalid parameters.", 400},
79  {rpcISSUE_MALFORMED, "issueMalformed", "Issue is malformed.", 400},
80  {rpcJSON_RPC, "json_rpc", "JSON-RPC transport error.", 500},
81  {rpcLGR_IDXS_INVALID, "lgrIdxsInvalid", "Ledger indexes invalid.", 400},
82  {rpcLGR_IDX_MALFORMED, "lgrIdxMalformed", "Ledger index malformed.", 400},
83  {rpcLGR_NOT_FOUND, "lgrNotFound", "Ledger not found.", 404},
84  {rpcLGR_NOT_VALIDATED, "lgrNotValidated", "Ledger not validated.", 202},
85  {rpcMASTER_DISABLED, "masterDisabled", "Master key is disabled.", 403},
86  {rpcNOT_ENABLED, "notEnabled", "Not enabled in configuration.", 501},
87  {rpcNOT_IMPL, "notImpl", "Not implemented.", 501},
88  {rpcNOT_READY, "notReady", "Not ready to handle this request.", 503},
89  {rpcNOT_SUPPORTED, "notSupported", "Operation not supported.", 501},
90  {rpcNO_CLOSED, "noClosed", "Closed ledger is unavailable.", 503},
91  {rpcNO_CURRENT, "noCurrent", "Current ledger is unavailable.", 503},
92  {rpcNOT_SYNCED, "notSynced", "Not synced to the network.", 503},
93  {rpcNO_EVENTS, "noEvents", "Current transport does not support events.", 405},
94  {rpcNO_NETWORK, "noNetwork", "Not synced to the network.", 503},
95  {rpcNO_PERMISSION, "noPermission", "You don't have permission for this command.", 401},
96  {rpcNO_PF_REQUEST, "noPathRequest", "No pathfinding request in progress.", 404},
97  {rpcOBJECT_NOT_FOUND, "objectNotFound", "The requested object was not found.", 404},
98  {rpcPUBLIC_MALFORMED, "publicMalformed", "Public key is malformed.", 400},
99  {rpcREPORTING_UNSUPPORTED, "reportingUnsupported", "Requested operation not supported by reporting mode server", 405},
100  {rpcSENDMAX_MALFORMED, "sendMaxMalformed", "SendMax amount malformed.", 400},
101  {rpcSIGNING_MALFORMED, "signingMalformed", "Signing of transaction is malformed.", 400},
102  {rpcSLOW_DOWN, "slowDown", "You are placing too much load on the server.", 429},
103  {rpcSRC_ACT_MALFORMED, "srcActMalformed", "Source account is malformed.", 400},
104  {rpcSRC_ACT_MISSING, "srcActMissing", "Source account not provided.", 400},
105  {rpcSRC_ACT_NOT_FOUND, "srcActNotFound", "Source account not found.", 404},
106  {rpcSRC_CUR_MALFORMED, "srcCurMalformed", "Source currency is malformed.", 400},
107  {rpcSRC_ISR_MALFORMED, "srcIsrMalformed", "Source issuer is malformed.", 400},
108  {rpcSTREAM_MALFORMED, "malformedStream", "Stream malformed.", 400},
109  {rpcTOO_BUSY, "tooBusy", "The server is too busy to help you now.", 503},
110  {rpcTXN_NOT_FOUND, "txnNotFound", "Transaction not found.", 404},
111  {rpcUNKNOWN_COMMAND, "unknownCmd", "Unknown method.", 405}};
112 // clang-format on
113 
114 // Sort and validate unorderedErrorInfos at compile time. Should be
115 // converted to consteval when get to C++20.
116 template <int M, int N>
117 constexpr auto
119 {
120  std::array<ErrorInfo, M> ret = {};
121 
122  for (ErrorInfo const& info : unordered)
123  {
124  if (info.code <= rpcSUCCESS || info.code > rpcLAST)
125  throw(std::out_of_range("Invalid error_code_i"));
126 
127  // The first valid code follows rpcSUCCESS immediately.
128  static_assert(rpcSUCCESS == 0, "Unexpected error_code_i layout.");
129  int const index{info.code - 1};
130 
131  if (ret[index].code != rpcUNKNOWN)
132  throw(std::invalid_argument("Duplicate error_code_i in list"));
133 
134  ret[index] = info;
135  }
136 
137  // Verify that all entries are filled in starting with 1 and proceeding
138  // to rpcLAST.
139  //
140  // It's okay for there to be missing entries; they will contain the code
141  // rpcUNKNOWN. But other than that all entries should match their index.
142  int codeCount{0};
143  int expect{rpcBAD_SYNTAX - 1};
144  for (ErrorInfo const& info : ret)
145  {
146  ++expect;
147  if (info.code == rpcUNKNOWN)
148  continue;
149 
150  if (info.code != expect)
151  throw(std::invalid_argument("Empty error_code_i in list"));
152  ++codeCount;
153  }
154  if (expect != rpcLAST)
155  throw(std::invalid_argument("Insufficient list entries"));
156  if (codeCount != N)
157  throw(std::invalid_argument("Bad handling of unorderedErrorInfos"));
158 
159  return ret;
160 }
161 
162 constexpr auto sortedErrorInfos{sortErrorInfos<rpcLAST>(unorderedErrorInfos)};
163 
165 
166 } // namespace detail
167 
168 //------------------------------------------------------------------------------
169 
170 ErrorInfo const&
172 {
173  if (code <= rpcSUCCESS || code > rpcLAST)
174  return detail::unknownError;
175  return detail::sortedErrorInfos[code - 1];
176 }
177 
180 {
181  Json::Value json;
182  inject_error(code, json);
183  return json;
184 }
185 
187 make_error(error_code_i code, std::string const& message)
188 {
189  Json::Value json;
190  inject_error(code, message, json);
191  return json;
192 }
193 
194 bool
196 {
197  if (json.isObject() && json.isMember(jss::error))
198  return true;
199  return false;
200 }
201 
202 int
204 {
205  return get_error_info(code).http_status;
206 }
207 
208 } // namespace RPC
209 
212 {
213  assert(RPC::contains_error(jv));
214  return jv[jss::error].asString() + jv[jss::error_message].asString();
215 }
216 
217 } // namespace ripple
ripple::rpcNO_NETWORK
@ rpcNO_NETWORK
Definition: ErrorCodes.h:66
ripple::rpcDB_DESERIALIZATION
@ rpcDB_DESERIALIZATION
Definition: ErrorCodes.h:134
ripple::rpcDST_AMT_MALFORMED
@ rpcDST_AMT_MALFORMED
Definition: ErrorCodes.h:106
ripple::rpcNOT_SUPPORTED
@ rpcNOT_SUPPORTED
Definition: ErrorCodes.h:132
ripple::rpcLGR_IDXS_INVALID
@ rpcLGR_IDXS_INVALID
Definition: ErrorCodes.h:112
Json::Value::isObject
bool isObject() const
Definition: json_value.cpp:1027
std::string
STL class.
ripple::rpcINVALID_PARAMS
@ rpcINVALID_PARAMS
Definition: ErrorCodes.h:84
ripple::RPC::ErrorInfo::http_status
int http_status
Definition: ErrorCodes.h:203
ripple::RPC::get_error_info
ErrorInfo const & get_error_info(error_code_i code)
Returns an ErrorInfo that reflects the error code.
Definition: ErrorCodes.cpp:171
ripple::rpcErrorString
std::string rpcErrorString(Json::Value const &jv)
Returns a single string with the contents of an RPC error.
Definition: ErrorCodes.cpp:211
ripple::RPC::detail::sortedErrorInfos
constexpr auto sortedErrorInfos
Definition: ErrorCodes.cpp:162
ripple::rpcSRC_ACT_NOT_FOUND
@ rpcSRC_ACT_NOT_FOUND
Definition: ErrorCodes.h:122
ripple::rpcJSON_RPC
@ rpcJSON_RPC
Definition: ErrorCodes.h:47
ripple::rpcSIGNING_MALFORMED
@ rpcSIGNING_MALFORMED
Definition: ErrorCodes.h:118
ripple::rpcNOT_READY
@ rpcNOT_READY
Definition: ErrorCodes.h:60
ripple::rpcEXCESSIVE_LGR_RANGE
@ rpcEXCESSIVE_LGR_RANGE
Definition: ErrorCodes.h:135
ripple::rpcTOO_BUSY
@ rpcTOO_BUSY
Definition: ErrorCodes.h:56
ripple::rpcATX_DEPRECATED
@ rpcATX_DEPRECATED
Definition: ErrorCodes.h:127
ripple::rpcLGR_NOT_FOUND
@ rpcLGR_NOT_FOUND
Definition: ErrorCodes.h:72
ripple::rpcREPORTING_UNSUPPORTED
@ rpcREPORTING_UNSUPPORTED
Definition: ErrorCodes.h:141
ripple::error_code_i
error_code_i
Definition: ErrorCodes.h:40
ripple::rpcOBJECT_NOT_FOUND
@ rpcOBJECT_NOT_FOUND
Definition: ErrorCodes.h:143
ripple::rpcAMENDMENT_BLOCKED
@ rpcAMENDMENT_BLOCKED
Definition: ErrorCodes.h:61
stdexcept
ripple::RPC::detail::sortErrorInfos
constexpr auto sortErrorInfos(ErrorInfo const (&unordered)[N]) -> std::array< ErrorInfo, M >
Definition: ErrorCodes.cpp:118
ripple::rpcSUCCESS
@ rpcSUCCESS
Definition: ErrorCodes.h:44
ripple::rpcSLOW_DOWN
@ rpcSLOW_DOWN
Definition: ErrorCodes.h:57
ripple::RPC::contains_error
bool contains_error(Json::Value const &json)
Returns true if the json contains an rpc error specification.
Definition: ErrorCodes.cpp:195
ripple::rpcSRC_ACT_MISSING
@ rpcSRC_ACT_MISSING
Definition: ErrorCodes.h:121
ripple::rpcALREADY_SINGLE_SIG
@ rpcALREADY_SINGLE_SIG
Definition: ErrorCodes.h:92
ripple::rpcBAD_SEED
@ rpcBAD_SEED
Definition: ErrorCodes.h:99
ripple::rpcHIGH_FEE
@ rpcHIGH_FEE
Definition: ErrorCodes.h:58
ripple::rpcPUBLIC_MALFORMED
@ rpcPUBLIC_MALFORMED
Definition: ErrorCodes.h:117
ripple::rpcACT_NOT_FOUND
@ rpcACT_NOT_FOUND
Definition: ErrorCodes.h:70
array
ripple::rpcTXN_NOT_FOUND
@ rpcTXN_NOT_FOUND
Definition: ErrorCodes.h:80
ripple::rpcSRC_ISR_MALFORMED
@ rpcSRC_ISR_MALFORMED
Definition: ErrorCodes.h:125
ripple::rpcSTREAM_MALFORMED
@ rpcSTREAM_MALFORMED
Definition: ErrorCodes.h:126
ripple::rpcNOT_ENABLED
@ rpcNOT_ENABLED
Definition: ErrorCodes.h:59
ripple::rpcNO_EVENTS
@ rpcNO_EVENTS
Definition: ErrorCodes.h:54
Json::Value::isMember
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: json_value.cpp:932
ripple::rpcNO_CURRENT
@ rpcNO_CURRENT
Definition: ErrorCodes.h:65
std::invalid_argument
STL class.
ripple::RPC::ErrorInfo
Maps an rpc error code to its token, default message, and HTTP status.
Definition: ErrorCodes.h:169
ripple::rpcDST_ISR_MALFORMED
@ rpcDST_ISR_MALFORMED
Definition: ErrorCodes.h:108
ripple::rpcCOMMAND_MISSING
@ rpcCOMMAND_MISSING
Definition: ErrorCodes.h:102
ripple::rpcDST_ACT_MALFORMED
@ rpcDST_ACT_MALFORMED
Definition: ErrorCodes.h:103
ripple::rpcALREADY_MULTISIG
@ rpcALREADY_MULTISIG
Definition: ErrorCodes.h:91
ripple::rpcLAST
@ rpcLAST
Definition: ErrorCodes.h:148
ripple::RPC::detail::unknownError
constexpr ErrorInfo unknownError
Definition: ErrorCodes.cpp:164
ripple::rpcINTERNAL
@ rpcINTERNAL
Definition: ErrorCodes.h:130
ripple::rpcCHANNEL_AMT_MALFORMED
@ rpcCHANNEL_AMT_MALFORMED
Definition: ErrorCodes.h:101
ripple::rpcDST_ACT_NOT_FOUND
@ rpcDST_ACT_NOT_FOUND
Definition: ErrorCodes.h:105
ripple::rpcNOT_IMPL
@ rpcNOT_IMPL
Definition: ErrorCodes.h:131
ripple::rpcSRC_ACT_MALFORMED
@ rpcSRC_ACT_MALFORMED
Definition: ErrorCodes.h:120
ripple::RPC::error_code_http_status
int error_code_http_status(error_code_i code)
Returns http status that corresponds to the error code.
Definition: ErrorCodes.cpp:203
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::rpcFORBIDDEN
@ rpcFORBIDDEN
Definition: ErrorCodes.h:48
ripple::rpcACT_MALFORMED
@ rpcACT_MALFORMED
Definition: ErrorCodes.h:90
ripple::rpcBAD_SYNTAX
@ rpcBAD_SYNTAX
Definition: ErrorCodes.h:46
ripple::rpcUNKNOWN_COMMAND
@ rpcUNKNOWN_COMMAND
Definition: ErrorCodes.h:85
ripple::rpcLGR_NOT_VALIDATED
@ rpcLGR_NOT_VALIDATED
Definition: ErrorCodes.h:73
ripple::rpcNO_PERMISSION
@ rpcNO_PERMISSION
Definition: ErrorCodes.h:53
cassert
ripple::rpcFAILED_TO_FORWARD
@ rpcFAILED_TO_FORWARD
Definition: ErrorCodes.h:140
ripple::rpcLGR_IDX_MALFORMED
@ rpcLGR_IDX_MALFORMED
Definition: ErrorCodes.h:113
ripple::rpcCHANNEL_MALFORMED
@ rpcCHANNEL_MALFORMED
Definition: ErrorCodes.h:100
ripple::rpcDST_AMT_MISSING
@ rpcDST_AMT_MISSING
Definition: ErrorCodes.h:107
ripple::rpcUNKNOWN
@ rpcUNKNOWN
Definition: ErrorCodes.h:42
std::out_of_range
STL class.
ripple::rpcBAD_MARKET
@ rpcBAD_MARKET
Definition: ErrorCodes.h:97
ripple::rpcINVALID_LGR_RANGE
@ rpcINVALID_LGR_RANGE
Definition: ErrorCodes.h:136
ripple::rpcSRC_CUR_MALFORMED
@ rpcSRC_CUR_MALFORMED
Definition: ErrorCodes.h:124
ripple::rpcISSUE_MALFORMED
@ rpcISSUE_MALFORMED
Definition: ErrorCodes.h:146
ripple::rpcDST_ACT_MISSING
@ rpcDST_ACT_MISSING
Definition: ErrorCodes.h:104
ripple::rpcNO_CLOSED
@ rpcNO_CLOSED
Definition: ErrorCodes.h:64
ripple::rpcBAD_SECRET
@ rpcBAD_SECRET
Definition: ErrorCodes.h:98
ripple::rpcBAD_ISSUER
@ rpcBAD_ISSUER
Definition: ErrorCodes.h:96
ripple::RPC::detail::unorderedErrorInfos
constexpr static ErrorInfo unorderedErrorInfos[]
Definition: ErrorCodes.cpp:47
ripple::RPC::inject_error
void inject_error(error_code_i code, JsonValue &json)
Add or update the json update to reflect the error code.
Definition: ErrorCodes.h:214
ripple::rpcMASTER_DISABLED
@ rpcMASTER_DISABLED
Definition: ErrorCodes.h:74
ripple::RPC::make_error
Json::Value make_error(error_code_i code)
Returns a new json object that reflects the error code.
Definition: ErrorCodes.cpp:179
ripple::rpcBAD_FEATURE
@ rpcBAD_FEATURE
Definition: ErrorCodes.h:95
ripple::rpcNO_PF_REQUEST
@ rpcNO_PF_REQUEST
Definition: ErrorCodes.h:86
ripple::rpcNOT_SYNCED
@ rpcNOT_SYNCED
Definition: ErrorCodes.h:67
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::rpcEXPIRED_VALIDATOR_LIST
@ rpcEXPIRED_VALIDATOR_LIST
Definition: ErrorCodes.h:137
ripple::rpcSENDMAX_MALFORMED
@ rpcSENDMAX_MALFORMED
Definition: ErrorCodes.h:119
ripple::rpcBAD_KEY_TYPE
@ rpcBAD_KEY_TYPE
Definition: ErrorCodes.h:133
Json::Value::asString
std::string asString() const
Returns the unquoted string value.
Definition: json_value.cpp:469