From 89b3bf07960a0980ee5de448333290f33bdb5871 Mon Sep 17 00:00:00 2001 From: Scott Schurr Date: Fri, 28 Jun 2019 19:51:19 -0700 Subject: [PATCH] Stabilize RPC error code values: The original intent was that RPC error codes were not stable. But those codes were made available through the API, so some users came to depend on the code values. This change adapts to the current state of affairs. --- src/ripple/protocol/ErrorCodes.h | 148 ++++++++++++++---------- src/ripple/protocol/impl/ErrorCodes.cpp | 24 +++- 2 files changed, 106 insertions(+), 66 deletions(-) diff --git a/src/ripple/protocol/ErrorCodes.h b/src/ripple/protocol/ErrorCodes.h index 589209cc3..c8e281455 100644 --- a/src/ripple/protocol/ErrorCodes.h +++ b/src/ripple/protocol/ErrorCodes.h @@ -27,82 +27,110 @@ namespace ripple { // VFALCO NOTE These are outside the RPC namespace +// NOTE: Although the precise numeric values of these codes were never +// intended to be stable, several API endpoints include the numeric values. +// Some users came to rely on the values, meaning that renumbering would be +// a breaking change for those users. +// +// We therefore treat the range of values as stable although they are not +// and are subject to change. +// +// Please only append to this table. Do not "fill-in" gaps and do not re-use +// or repurpose error code values. enum error_code_i { - rpcUNKNOWN = -1, // Represents codes not listed in this enumeration + // -1 represents codes not listed in this enumeration + rpcUNKNOWN = -1, - rpcSUCCESS = 0, + rpcSUCCESS = 0, - rpcBAD_SYNTAX, // Must be 1 to print usage to command line. - rpcJSON_RPC, - rpcFORBIDDEN, - - // Error numbers beyond this line are not stable between versions. - // Programs should use error tokens. + rpcBAD_SYNTAX = 1, + rpcJSON_RPC = 2, + rpcFORBIDDEN = 3, // Misc failure - rpcNO_PERMISSION, - rpcNO_EVENTS, - rpcTOO_BUSY, - rpcSLOW_DOWN, - rpcHIGH_FEE, - rpcNOT_ENABLED, - rpcNOT_READY, - rpcAMENDMENT_BLOCKED, + // unused 4, + // unused 5, + rpcNO_PERMISSION = 6, + rpcNO_EVENTS = 7, + // unused 8, + rpcTOO_BUSY = 9, + rpcSLOW_DOWN = 10, + rpcHIGH_FEE = 11, + rpcNOT_ENABLED = 12, + rpcNOT_READY = 13, + rpcAMENDMENT_BLOCKED = 14, // Networking - rpcNO_CLOSED, - rpcNO_CURRENT, - rpcNO_NETWORK, + rpcNO_CLOSED = 15, + rpcNO_CURRENT = 16, + rpcNO_NETWORK = 17, // Ledger state - rpcACT_NOT_FOUND, - rpcLGR_NOT_FOUND, - rpcLGR_NOT_VALIDATED, - rpcMASTER_DISABLED, - rpcTXN_NOT_FOUND, + // unused 18, + rpcACT_NOT_FOUND = 19, + // unused 20, + rpcLGR_NOT_FOUND = 21, + rpcLGR_NOT_VALIDATED = 22, + rpcMASTER_DISABLED = 23, + // unused 24, + // unused 25, + // unused 26, + // unused 27, + // unused 28, + rpcTXN_NOT_FOUND = 29, + // unused 30, // Malformed command - rpcINVALID_PARAMS, - rpcUNKNOWN_COMMAND, - rpcNO_PF_REQUEST, + rpcINVALID_PARAMS = 31, + rpcUNKNOWN_COMMAND = 32, + rpcNO_PF_REQUEST = 33, // Bad parameter - rpcACT_BITCOIN, - rpcACT_MALFORMED, - rpcALREADY_MULTISIG, - rpcALREADY_SINGLE_SIG, - rpcBAD_FEATURE, - rpcBAD_ISSUER, - rpcBAD_MARKET, - rpcBAD_SECRET, - rpcBAD_SEED, - rpcCHANNEL_MALFORMED, - rpcCHANNEL_AMT_MALFORMED, - rpcCOMMAND_MISSING, - rpcDST_ACT_MALFORMED, - rpcDST_ACT_MISSING, - rpcDST_ACT_NOT_FOUND, - rpcDST_AMT_MALFORMED, - rpcDST_AMT_MISSING, - rpcDST_ISR_MALFORMED, - rpcLGR_IDXS_INVALID, - rpcLGR_IDX_MALFORMED, - rpcPUBLIC_MALFORMED, - rpcSIGNING_MALFORMED, - rpcSENDMAX_MALFORMED, - rpcSRC_ACT_MALFORMED, - rpcSRC_ACT_MISSING, - rpcSRC_ACT_NOT_FOUND, - rpcSRC_CUR_MALFORMED, - rpcSRC_ISR_MALFORMED, - rpcSTREAM_MALFORMED, - rpcATX_DEPRECATED, + rpcACT_BITCOIN = 34, + rpcACT_MALFORMED = 35, + rpcALREADY_MULTISIG = 36, + rpcALREADY_SINGLE_SIG = 37, + // unused 38, + // unused 39, + rpcBAD_FEATURE = 40, + rpcBAD_ISSUER = 41, + rpcBAD_MARKET = 42, + rpcBAD_SECRET = 43, + rpcBAD_SEED = 44, + rpcCHANNEL_MALFORMED = 45, + rpcCHANNEL_AMT_MALFORMED = 46, + rpcCOMMAND_MISSING = 47, + rpcDST_ACT_MALFORMED = 48, + rpcDST_ACT_MISSING = 49, + rpcDST_ACT_NOT_FOUND = 50, + rpcDST_AMT_MALFORMED = 51, + rpcDST_AMT_MISSING = 52, + rpcDST_ISR_MALFORMED = 53, + // unused 54, + // unused 55, + // unused 56, + rpcLGR_IDXS_INVALID = 57, + rpcLGR_IDX_MALFORMED = 58, + // unused 59, + // unused 60, + // unused 61, + rpcPUBLIC_MALFORMED = 62, + rpcSIGNING_MALFORMED = 63, + rpcSENDMAX_MALFORMED = 64, + rpcSRC_ACT_MALFORMED = 65, + rpcSRC_ACT_MISSING = 66, + rpcSRC_ACT_NOT_FOUND = 67, + // unused 68, + rpcSRC_CUR_MALFORMED = 69, + rpcSRC_ISR_MALFORMED = 70, + rpcSTREAM_MALFORMED = 71, + rpcATX_DEPRECATED = 72, // Internal error (should never happen) - rpcINTERNAL, // Generic internal error. - rpcNOT_IMPL, - rpcNOT_SUPPORTED, + rpcINTERNAL = 73, // Generic internal error. + rpcNOT_IMPL = 74, + rpcNOT_SUPPORTED = 75, rpcLAST = rpcNOT_SUPPORTED // rpcLAST should always equal the last code. }; diff --git a/src/ripple/protocol/impl/ErrorCodes.cpp b/src/ripple/protocol/impl/ErrorCodes.cpp index 019a2c1da..10aa65c81 100644 --- a/src/ripple/protocol/impl/ErrorCodes.cpp +++ b/src/ripple/protocol/impl/ErrorCodes.cpp @@ -111,11 +111,11 @@ struct ErrorInfoArray // Sort and validate unorderedErrorInfos at compile time. Should be // converted to consteval when get to C++20. -template +template constexpr auto -sortErrorInfos (ErrorInfo const (&unordered)[N]) -> ErrorInfoArray +sortErrorInfos (ErrorInfo const (&unordered)[N]) -> ErrorInfoArray { - ErrorInfoArray ret; + ErrorInfoArray ret; for (ErrorInfo const& info : unordered) { @@ -136,19 +136,31 @@ sortErrorInfos (ErrorInfo const (&unordered)[N]) -> ErrorInfoArray // Verify that all entries are filled in starting with 1 and proceeding // to rpcLAST. - int expect = 0; + // + // It's okay for there to be missing entries; they will contain the code + // rpcUNKNOWN. But other than that all entries should match their index. + int codeCount {0}; + int expect {rpcBAD_SYNTAX - 1}; for (ErrorInfo const& info : ret.infos) { - if (info.code != ++expect) + ++expect; + if (info.code == rpcUNKNOWN) + continue; + + if (info.code != expect) throw (std::invalid_argument ("Empty error_code_i in list")); + ++codeCount; } if (expect != rpcLAST) throw (std::invalid_argument ("Insufficient list entries")); + if (codeCount != N) + throw (std::invalid_argument ("Bad handling of unorderedErrorInfos")); return ret; } -constexpr auto sortedErrorInfos {sortErrorInfos(unorderedErrorInfos)}; +constexpr auto sortedErrorInfos {sortErrorInfos(unorderedErrorInfos)}; + constexpr ErrorInfo unknownError; } // detail