univalue: Return more detailed type check error messages

This commit is contained in:
MacroFake
2022-07-18 11:13:22 +02:00
parent fafab147e7
commit fae5ce8795
11 changed files with 41 additions and 40 deletions

View File

@@ -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;
@@ -130,7 +131,7 @@ 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);
}
@@ -138,9 +139,7 @@ template <typename Int>
Int UniValue::getInt() const
{
static_assert(std::is_integral<Int>::value);
if (typ != VNUM) {
throw std::runtime_error("JSON value is not an integer as expected");
}
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{}) {

View File

@@ -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) {

View File

@@ -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;
}