diff options
author | fanquake <fanquake@gmail.com> | 2022-07-19 11:19:12 +0100 |
---|---|---|
committer | fanquake <fanquake@gmail.com> | 2022-07-19 11:24:53 +0100 |
commit | 47dad42833d535aee6071526bec9df1b2497bad3 (patch) | |
tree | 46ac07305f7c3a3dda2ea86762d5e0f73e14f534 /src | |
parent | 6d8707b21d3a5b4abb76b773a69f2bfac22bcd93 (diff) | |
parent | fae5ce8795080018875227aee8613677f92e99ce (diff) |
Merge bitcoin/bitcoin#25629: univalue: Return more detailed type check error messages
fae5ce8795080018875227aee8613677f92e99ce univalue: Return more detailed type check error messages (MacroFake)
fafab147e7ff41ab1b961349f20a364f6bf847d2 move-only: Move UniValue::getInt definition to keep class with definitions only (MacroFake)
Pull request description:
Print the current type and the expected type
ACKs for top commit:
aureleoules:
ACK fae5ce8795080018875227aee8613677f92e99ce.
Tree-SHA512: 4ae720a012ff8245baf5cd7f844f93b946c58feebe62de6dfd84ebc5c8afb988295a94de7c01aef98aaf4c6228f7184ed622f37079c738924617e0f336ac5b6e
Diffstat (limited to 'src')
-rw-r--r-- | src/univalue/include/univalue.h | 30 | ||||
-rw-r--r-- | src/univalue/lib/univalue.cpp | 19 | ||||
-rw-r--r-- | src/univalue/lib/univalue_get.cpp | 19 |
3 files changed, 36 insertions, 32 deletions
diff --git a/src/univalue/include/univalue.h b/src/univalue/include/univalue.h index 5cb8268472..dff544f96f 100644 --- a/src/univalue/include/univalue.h +++ b/src/univalue/include/univalue.h @@ -106,6 +106,7 @@ private: std::vector<std::string> keys; std::vector<UniValue> values; + void checkType(const VType& expected) const; bool findKey(const std::string& key, size_t& retIdx) const; void writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const; void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const; @@ -116,19 +117,7 @@ public: const std::vector<std::string>& getKeys() const; const std::vector<UniValue>& getValues() const; template <typename Int> - auto getInt() const - { - static_assert(std::is_integral<Int>::value); - if (typ != VNUM) { - throw std::runtime_error("JSON value is not an integer as expected"); - } - Int result; - const auto [first_nonmatching, error_condition] = std::from_chars(val.data(), val.data() + val.size(), result); - if (first_nonmatching != val.data() + val.size() || error_condition != std::errc{}) { - throw std::runtime_error("JSON integer out of range"); - } - return result; - } + Int getInt() const; bool get_bool() const; const std::string& get_str() const; double get_real() const; @@ -142,10 +131,23 @@ public: template <class It> void UniValue::push_backV(It first, It last) { - if (typ != VARR) throw std::runtime_error{"JSON value is not an array as expected"}; + checkType(VARR); values.insert(values.end(), first, last); } +template <typename Int> +Int UniValue::getInt() const +{ + static_assert(std::is_integral<Int>::value); + checkType(VNUM); + Int result; + const auto [first_nonmatching, error_condition] = std::from_chars(val.data(), val.data() + val.size(), result); + if (first_nonmatching != val.data() + val.size() || error_condition != std::errc{}) { + throw std::runtime_error("JSON integer out of range"); + } + return result; +} + enum jtokentype { JTOK_ERR = -1, JTOK_NONE = 0, // eof diff --git a/src/univalue/lib/univalue.cpp b/src/univalue/lib/univalue.cpp index ac6f31a5a9..051bc8eba6 100644 --- a/src/univalue/lib/univalue.cpp +++ b/src/univalue/lib/univalue.cpp @@ -110,21 +110,21 @@ bool UniValue::setObject() void UniValue::push_back(const UniValue& val_) { - if (typ != VARR) throw std::runtime_error{"JSON value is not an array as expected"}; + checkType(VARR); values.push_back(val_); } void UniValue::push_backV(const std::vector<UniValue>& vec) { - if (typ != VARR) throw std::runtime_error{"JSON value is not an array as expected"}; + checkType(VARR); values.insert(values.end(), vec.begin(), vec.end()); } void UniValue::__pushKV(const std::string& key, const UniValue& val_) { - if (typ != VOBJ) throw std::runtime_error{"JSON value is not an object as expected"}; + checkType(VOBJ); keys.push_back(key); values.push_back(val_); @@ -132,7 +132,7 @@ void UniValue::__pushKV(const std::string& key, const UniValue& val_) void UniValue::pushKV(const std::string& key, const UniValue& val_) { - if (typ != VOBJ) throw std::runtime_error{"JSON value is not an object as expected"}; + checkType(VOBJ); size_t idx; if (findKey(key, idx)) @@ -143,7 +143,8 @@ void UniValue::pushKV(const std::string& key, const UniValue& val_) void UniValue::pushKVs(const UniValue& obj) { - if (typ != VOBJ || obj.typ != VOBJ) throw std::runtime_error{"JSON value is not an object as expected"}; + checkType(VOBJ); + obj.checkType(VOBJ); for (size_t i = 0; i < obj.keys.size(); i++) __pushKV(obj.keys[i], obj.values.at(i)); @@ -213,6 +214,14 @@ const UniValue& UniValue::operator[](size_t index) const return values.at(index); } +void UniValue::checkType(const VType& expected) const +{ + if (typ != expected) { + throw std::runtime_error{"JSON value of type " + std::string{uvTypeName(typ)} + " is not of expected type " + + std::string{uvTypeName(expected)}}; + } +} + const char *uvTypeName(UniValue::VType t) { switch (t) { diff --git a/src/univalue/lib/univalue_get.cpp b/src/univalue/lib/univalue_get.cpp index 9bbdb1fe69..5c58f388dd 100644 --- a/src/univalue/lib/univalue_get.cpp +++ b/src/univalue/lib/univalue_get.cpp @@ -46,8 +46,7 @@ bool ParseDouble(const std::string& str, double *out) const std::vector<std::string>& UniValue::getKeys() const { - if (typ != VOBJ) - throw std::runtime_error("JSON value is not an object as expected"); + checkType(VOBJ); return keys; } @@ -60,22 +59,19 @@ const std::vector<UniValue>& UniValue::getValues() const bool UniValue::get_bool() const { - if (typ != VBOOL) - throw std::runtime_error("JSON value is not a boolean as expected"); + checkType(VBOOL); return getBool(); } const std::string& UniValue::get_str() const { - if (typ != VSTR) - throw std::runtime_error("JSON value is not a string as expected"); + checkType(VSTR); return getValStr(); } double UniValue::get_real() const { - if (typ != VNUM) - throw std::runtime_error("JSON value is not a number as expected"); + checkType(VNUM); double retval; if (!ParseDouble(getValStr(), &retval)) throw std::runtime_error("JSON double out of range"); @@ -84,15 +80,12 @@ double UniValue::get_real() const const UniValue& UniValue::get_obj() const { - if (typ != VOBJ) - throw std::runtime_error("JSON value is not an object as expected"); + checkType(VOBJ); return *this; } const UniValue& UniValue::get_array() const { - if (typ != VARR) - throw std::runtime_error("JSON value is not an array as expected"); + checkType(VARR); return *this; } - |