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 <cassert>
22 #include <stdexcept>
23 
24 namespace ripple {
25 namespace RPC {
26 
27 namespace detail {
28 
29 // Unordered array of ErrorInfos, so we don't have to maintain the list
30 // ordering by hand.
31 //
32 // This array will be omitted from the object file; only the sorted version
33 // will remain in the object file. But the string literals will remain.
34 constexpr static ErrorInfo unorderedErrorInfos[]
35 {
36  {rpcACT_BITCOIN, "actBitcoin", "Account is bitcoin address."},
37  {rpcACT_MALFORMED, "actMalformed", "Account malformed."},
38  {rpcACT_NOT_FOUND, "actNotFound", "Account not found."},
39  {rpcALREADY_MULTISIG, "alreadyMultisig", "Already multisigned."},
40  {rpcALREADY_SINGLE_SIG, "alreadySingleSig", "Already single-signed."},
41  {rpcAMENDMENT_BLOCKED, "amendmentBlocked", "Amendment blocked, need upgrade."},
42  {rpcATX_DEPRECATED, "deprecated", "Use the new API or specify a ledger range."},
43  {rpcBAD_KEY_TYPE, "badKeyType", "Bad key type."},
44  {rpcBAD_FEATURE, "badFeature", "Feature unknown or invalid."},
45  {rpcBAD_ISSUER, "badIssuer", "Issuer account malformed."},
46  {rpcBAD_MARKET, "badMarket", "No such market."},
47  {rpcBAD_SECRET, "badSecret", "Secret does not match account."},
48  {rpcBAD_SEED, "badSeed", "Disallowed seed."},
49  {rpcBAD_SYNTAX, "badSyntax", "Syntax error."},
50  {rpcCHANNEL_MALFORMED, "channelMalformed", "Payment channel is malformed."},
51  {rpcCHANNEL_AMT_MALFORMED, "channelAmtMalformed", "Payment channel amount is malformed."},
52  {rpcCOMMAND_MISSING, "commandMissing", "Missing command entry."},
53  {rpcDB_DESERIALIZATION, "dbDeserialization", "Database deserialization error."},
54  {rpcDST_ACT_MALFORMED, "dstActMalformed", "Destination account is malformed."},
55  {rpcDST_ACT_MISSING, "dstActMissing", "Destination account not provided."},
56  {rpcDST_ACT_NOT_FOUND, "dstActNotFound", "Destination account not found."},
57  {rpcDST_AMT_MALFORMED, "dstAmtMalformed", "Destination amount/currency/issuer is malformed."},
58  {rpcDST_AMT_MISSING, "dstAmtMissing", "Destination amount/currency/issuer is missing."},
59  {rpcDST_ISR_MALFORMED, "dstIsrMalformed", "Destination issuer is malformed."},
60  {rpcEXCESSIVE_LGR_RANGE, "excessiveLgrRange", "Ledger range exceeds 1000."},
61  {rpcFORBIDDEN, "forbidden", "Bad credentials."},
62  {rpcHIGH_FEE, "highFee", "Current transaction fee exceeds your limit."},
63  {rpcINTERNAL, "internal", "Internal error."},
64  {rpcINVALID_LGR_RANGE, "invalidLgrRange", "Ledger range is invalid."},
65  {rpcINVALID_PARAMS, "invalidParams", "Invalid parameters."},
66  {rpcJSON_RPC, "json_rpc", "JSON-RPC transport error."},
67  {rpcLGR_IDXS_INVALID, "lgrIdxsInvalid", "Ledger indexes invalid."},
68  {rpcLGR_IDX_MALFORMED, "lgrIdxMalformed", "Ledger index malformed."},
69  {rpcLGR_NOT_FOUND, "lgrNotFound", "Ledger not found."},
70  {rpcLGR_NOT_VALIDATED, "lgrNotValidated", "Ledger not validated."},
71  {rpcMASTER_DISABLED, "masterDisabled", "Master key is disabled."},
72  {rpcNOT_ENABLED, "notEnabled", "Not enabled in configuration."},
73  {rpcNOT_IMPL, "notImpl", "Not implemented."},
74  {rpcNOT_READY, "notReady", "Not ready to handle this request."},
75  {rpcNOT_SUPPORTED, "notSupported", "Operation not supported."},
76  {rpcNO_CLOSED, "noClosed", "Closed ledger is unavailable."},
77  {rpcNO_CURRENT, "noCurrent", "Current ledger is unavailable."},
78  {rpcNO_EVENTS, "noEvents", "Current transport does not support events."},
79  {rpcNO_NETWORK, "noNetwork", "Not synced to Ripple network."},
80  {rpcNO_PERMISSION, "noPermission", "You don't have permission for this command."},
81  {rpcNO_PF_REQUEST, "noPathRequest", "No pathfinding request in progress."},
82  {rpcPUBLIC_MALFORMED, "publicMalformed", "Public key is malformed."},
83  {rpcSIGNING_MALFORMED, "signingMalformed", "Signing of transaction is malformed."},
84  {rpcSLOW_DOWN, "slowDown", "You are placing too much load on the server."},
85  {rpcSRC_ACT_MALFORMED, "srcActMalformed", "Source account is malformed."},
86  {rpcSRC_ACT_MISSING, "srcActMissing", "Source account not provided."},
87  {rpcSRC_ACT_NOT_FOUND, "srcActNotFound", "Source account not found."},
88  {rpcSRC_CUR_MALFORMED, "srcCurMalformed", "Source currency is malformed."},
89  {rpcSRC_ISR_MALFORMED, "srcIsrMalformed", "Source issuer is malformed."},
90  {rpcSTREAM_MALFORMED, "malformedStream", "Stream malformed."},
91  {rpcTOO_BUSY, "tooBusy", "The server is too busy to help you now."},
92  {rpcTXN_NOT_FOUND, "txnNotFound", "Transaction not found."},
93  {rpcUNKNOWN_COMMAND, "unknownCmd", "Unknown method."},
94  {rpcSENDMAX_MALFORMED, "sendMaxMalformed", "SendMax amount malformed."}
95 };
96 
97 // C++ does not allow you to return an array from a function. You must
98 // return an object which may in turn contain an array. The following
99 // struct is simply defined so the enclosed array can be returned from a
100 // constexpr function.
101 //
102 // In C++17 this struct can be replaced by a std::array. But in C++14
103 // the constexpr methods of a std::array are not sufficient to perform the
104 // necessary work at compile time.
105 template <int N>
107 {
108  // Visual Studio doesn't treat a templated aggregate as an aggregate.
109  // So, for Visual Studio, we define a constexpr default constructor.
110  constexpr ErrorInfoArray()
111  : infos {}
112  { }
113 
115 };
116 
117 // Sort and validate unorderedErrorInfos at compile time. Should be
118 // converted to consteval when get to C++20.
119 template<int M, int N>
120 constexpr auto
121 sortErrorInfos (ErrorInfo const (&unordered)[N]) -> ErrorInfoArray<M>
122 {
123  ErrorInfoArray<M> ret;
124 
125  for (ErrorInfo const& info : unordered)
126  {
127  if (info.code <= rpcSUCCESS || info.code > rpcLAST)
128  throw (std::out_of_range ("Invalid error_code_i"));
129 
130  // The first valid code follows rpcSUCCESS immediately.
131  static_assert (rpcSUCCESS == 0, "Unexpected error_code_i layout.");
132  int const index {info.code - 1};
133 
134  if (ret.infos[index].code != rpcUNKNOWN)
135  throw (std::invalid_argument ("Duplicate error_code_i in list"));
136 
137  ret.infos[index].code = info.code;
138  ret.infos[index].token = info.token;
139  ret.infos[index].message = info.message;
140  }
141 
142  // Verify that all entries are filled in starting with 1 and proceeding
143  // to rpcLAST.
144  //
145  // It's okay for there to be missing entries; they will contain the code
146  // rpcUNKNOWN. But other than that all entries should match their index.
147  int codeCount {0};
148  int expect {rpcBAD_SYNTAX - 1};
149  for (ErrorInfo const& info : ret.infos)
150  {
151  ++expect;
152  if (info.code == rpcUNKNOWN)
153  continue;
154 
155  if (info.code != expect)
156  throw (std::invalid_argument ("Empty error_code_i in list"));
157  ++codeCount;
158  }
159  if (expect != rpcLAST)
160  throw (std::invalid_argument ("Insufficient list entries"));
161  if (codeCount != N)
162  throw (std::invalid_argument ("Bad handling of unorderedErrorInfos"));
163 
164  return ret;
165 }
166 
167 constexpr auto sortedErrorInfos {sortErrorInfos<rpcLAST>(unorderedErrorInfos)};
168 
170 
171 } // detail
172 
173 //------------------------------------------------------------------------------
174 
176 {
177  if (code <= rpcSUCCESS || code > rpcLAST)
178  return detail::unknownError;
179  return detail::sortedErrorInfos.infos[code - 1];
180 }
181 
183 {
184  Json::Value json;
185  inject_error (code, json);
186  return json;
187 }
188 
190 {
191  Json::Value json;
192  inject_error (code, message, json);
193  return json;
194 }
195 
196 bool contains_error (Json::Value const& json)
197 {
198  if (json.isObject() && json.isMember (jss::error))
199  return true;
200  return false;
201 }
202 
203 } // RPC
204 
206 {
207  assert(RPC::contains_error(jv));
208  return jv[jss::error].asString() +
209  jv[jss::error_message].asString();
210 }
211 
212 } // ripple
213 
ripple::rpcNO_NETWORK
@ rpcNO_NETWORK
Definition: ErrorCodes.h:67
ripple::rpcDB_DESERIALIZATION
@ rpcDB_DESERIALIZATION
Definition: ErrorCodes.h:135
ripple::rpcDST_AMT_MALFORMED
@ rpcDST_AMT_MALFORMED
Definition: ErrorCodes.h:107
ripple::rpcNOT_SUPPORTED
@ rpcNOT_SUPPORTED
Definition: ErrorCodes.h:133
ripple::rpcLGR_IDXS_INVALID
@ rpcLGR_IDXS_INVALID
Definition: ErrorCodes.h:113
Json::Value::isObject
bool isObject() const
Definition: json_value.cpp:1069
std::string
STL class.
ripple::rpcINVALID_PARAMS
@ rpcINVALID_PARAMS
Definition: ErrorCodes.h:85
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:175
ripple::rpcErrorString
std::string rpcErrorString(Json::Value const &jv)
Returns a single string with the contents of an RPC error.
Definition: ErrorCodes.cpp:205
ripple::RPC::detail::sortedErrorInfos
constexpr auto sortedErrorInfos
Definition: ErrorCodes.cpp:167
ripple::rpcSRC_ACT_NOT_FOUND
@ rpcSRC_ACT_NOT_FOUND
Definition: ErrorCodes.h:123
ripple::rpcJSON_RPC
@ rpcJSON_RPC
Definition: ErrorCodes.h:48
ripple::rpcSIGNING_MALFORMED
@ rpcSIGNING_MALFORMED
Definition: ErrorCodes.h:119
ripple::rpcNOT_READY
@ rpcNOT_READY
Definition: ErrorCodes.h:61
ripple::rpcEXCESSIVE_LGR_RANGE
@ rpcEXCESSIVE_LGR_RANGE
Definition: ErrorCodes.h:136
ripple::RPC::detail::ErrorInfoArray::infos
ErrorInfo infos[N]
Definition: ErrorCodes.cpp:114
ripple::rpcTOO_BUSY
@ rpcTOO_BUSY
Definition: ErrorCodes.h:57
ripple::rpcATX_DEPRECATED
@ rpcATX_DEPRECATED
Definition: ErrorCodes.h:128
ripple::rpcLGR_NOT_FOUND
@ rpcLGR_NOT_FOUND
Definition: ErrorCodes.h:73
ripple::error_code_i
error_code_i
Definition: ErrorCodes.h:40
ripple::rpcAMENDMENT_BLOCKED
@ rpcAMENDMENT_BLOCKED
Definition: ErrorCodes.h:62
stdexcept
ripple::rpcSUCCESS
@ rpcSUCCESS
Definition: ErrorCodes.h:45
ripple::rpcSLOW_DOWN
@ rpcSLOW_DOWN
Definition: ErrorCodes.h:58
ripple::RPC::contains_error
bool contains_error(Json::Value const &json)
Returns true if the json contains an rpc error specification.
Definition: ErrorCodes.cpp:196
ripple::rpcSRC_ACT_MISSING
@ rpcSRC_ACT_MISSING
Definition: ErrorCodes.h:122
ripple::rpcALREADY_SINGLE_SIG
@ rpcALREADY_SINGLE_SIG
Definition: ErrorCodes.h:93
ripple::rpcBAD_SEED
@ rpcBAD_SEED
Definition: ErrorCodes.h:100
ripple::rpcHIGH_FEE
@ rpcHIGH_FEE
Definition: ErrorCodes.h:59
ripple::rpcPUBLIC_MALFORMED
@ rpcPUBLIC_MALFORMED
Definition: ErrorCodes.h:118
ripple::rpcACT_NOT_FOUND
@ rpcACT_NOT_FOUND
Definition: ErrorCodes.h:71
ripple::rpcTXN_NOT_FOUND
@ rpcTXN_NOT_FOUND
Definition: ErrorCodes.h:81
ripple::rpcSRC_ISR_MALFORMED
@ rpcSRC_ISR_MALFORMED
Definition: ErrorCodes.h:126
ripple::rpcSTREAM_MALFORMED
@ rpcSTREAM_MALFORMED
Definition: ErrorCodes.h:127
ripple::rpcNOT_ENABLED
@ rpcNOT_ENABLED
Definition: ErrorCodes.h:60
ripple::rpcNO_EVENTS
@ rpcNO_EVENTS
Definition: ErrorCodes.h:55
Json::Value::isMember
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: json_value.cpp:961
ripple::rpcNO_CURRENT
@ rpcNO_CURRENT
Definition: ErrorCodes.h:66
std::invalid_argument
STL class.
ripple::RPC::ErrorInfo
Maps an rpc error code to its token and default message.
Definition: ErrorCodes.h:158
ripple::rpcDST_ISR_MALFORMED
@ rpcDST_ISR_MALFORMED
Definition: ErrorCodes.h:109
ripple::rpcCOMMAND_MISSING
@ rpcCOMMAND_MISSING
Definition: ErrorCodes.h:103
ripple::rpcDST_ACT_MALFORMED
@ rpcDST_ACT_MALFORMED
Definition: ErrorCodes.h:104
ripple::rpcALREADY_MULTISIG
@ rpcALREADY_MULTISIG
Definition: ErrorCodes.h:92
ripple::rpcLAST
@ rpcLAST
Definition: ErrorCodes.h:138
ripple::RPC::detail::unknownError
constexpr ErrorInfo unknownError
Definition: ErrorCodes.cpp:169
ripple::rpcACT_BITCOIN
@ rpcACT_BITCOIN
Definition: ErrorCodes.h:90
ripple::rpcINTERNAL
@ rpcINTERNAL
Definition: ErrorCodes.h:131
ripple::rpcCHANNEL_AMT_MALFORMED
@ rpcCHANNEL_AMT_MALFORMED
Definition: ErrorCodes.h:102
ripple::rpcDST_ACT_NOT_FOUND
@ rpcDST_ACT_NOT_FOUND
Definition: ErrorCodes.h:106
ripple::rpcNOT_IMPL
@ rpcNOT_IMPL
Definition: ErrorCodes.h:132
ripple::rpcSRC_ACT_MALFORMED
@ rpcSRC_ACT_MALFORMED
Definition: ErrorCodes.h:121
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:49
ripple::rpcACT_MALFORMED
@ rpcACT_MALFORMED
Definition: ErrorCodes.h:91
ripple::rpcBAD_SYNTAX
@ rpcBAD_SYNTAX
Definition: ErrorCodes.h:47
ripple::rpcUNKNOWN_COMMAND
@ rpcUNKNOWN_COMMAND
Definition: ErrorCodes.h:86
ripple::rpcLGR_NOT_VALIDATED
@ rpcLGR_NOT_VALIDATED
Definition: ErrorCodes.h:74
ripple::rpcNO_PERMISSION
@ rpcNO_PERMISSION
Definition: ErrorCodes.h:54
cassert
ripple::rpcLGR_IDX_MALFORMED
@ rpcLGR_IDX_MALFORMED
Definition: ErrorCodes.h:114
ripple::rpcCHANNEL_MALFORMED
@ rpcCHANNEL_MALFORMED
Definition: ErrorCodes.h:101
ripple::rpcDST_AMT_MISSING
@ rpcDST_AMT_MISSING
Definition: ErrorCodes.h:108
ripple::rpcUNKNOWN
@ rpcUNKNOWN
Definition: ErrorCodes.h:43
std::out_of_range
STL class.
ripple::rpcBAD_MARKET
@ rpcBAD_MARKET
Definition: ErrorCodes.h:98
ripple::rpcINVALID_LGR_RANGE
@ rpcINVALID_LGR_RANGE
Definition: ErrorCodes.h:137
ripple::rpcSRC_CUR_MALFORMED
@ rpcSRC_CUR_MALFORMED
Definition: ErrorCodes.h:125
ripple::rpcDST_ACT_MISSING
@ rpcDST_ACT_MISSING
Definition: ErrorCodes.h:105
ripple::RPC::detail::sortErrorInfos
constexpr auto sortErrorInfos(ErrorInfo const (&unordered)[N]) -> ErrorInfoArray< M >
Definition: ErrorCodes.cpp:121
ripple::rpcNO_CLOSED
@ rpcNO_CLOSED
Definition: ErrorCodes.h:65
ripple::rpcBAD_SECRET
@ rpcBAD_SECRET
Definition: ErrorCodes.h:99
ripple::RPC::detail::ErrorInfoArray
Definition: ErrorCodes.cpp:106
ripple::rpcBAD_ISSUER
@ rpcBAD_ISSUER
Definition: ErrorCodes.h:97
ripple::RPC::detail::unorderedErrorInfos
constexpr static ErrorInfo unorderedErrorInfos[]
Definition: ErrorCodes.cpp:35
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:185
ripple::RPC::detail::ErrorInfoArray::ErrorInfoArray
constexpr ErrorInfoArray()
Definition: ErrorCodes.cpp:110
ripple::rpcMASTER_DISABLED
@ rpcMASTER_DISABLED
Definition: ErrorCodes.h:75
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:182
ripple::rpcBAD_FEATURE
@ rpcBAD_FEATURE
Definition: ErrorCodes.h:96
ripple::rpcNO_PF_REQUEST
@ rpcNO_PF_REQUEST
Definition: ErrorCodes.h:87
Json::Value
Represents a JSON value.
Definition: json_value.h:141
ripple::rpcSENDMAX_MALFORMED
@ rpcSENDMAX_MALFORMED
Definition: ErrorCodes.h:120
ripple::RPC::ErrorInfo::code
error_code_i code
Definition: ErrorCodes.h:174
ripple::rpcBAD_KEY_TYPE
@ rpcBAD_KEY_TYPE
Definition: ErrorCodes.h:134
Json::Value::asString
std::string asString() const
Returns the unquoted string value.
Definition: json_value.cpp:482