Merge pull request #110 from baylesj/remote_throws

Add VALIJSON_USE_EXCEPTIONS mode
This commit is contained in:
Tristan Penman 2020-11-09 16:51:19 +11:00 committed by GitHub
commit c1e75c700f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 350 additions and 154 deletions

View File

@ -7,6 +7,7 @@ option(valijson_INSTALL_HEADERS "Install valijson headers." FALSE)
option(valijson_BUILD_EXAMPLES "Build valijson examples." FALSE)
option(valijson_BUILD_TESTS "Build valijson test suite." TRUE)
option(valijson_EXCLUDE_BOOST "Exclude Boost when building test suite." FALSE)
option(valijson_USE_EXCEPTIONS "Use exceptions in valijson and included libs." TRUE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
@ -38,6 +39,16 @@ else()
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
#TODO()
if(valijson_USE_EXCEPTIONS)
add_definitions(-DVALIJSON_USE_EXCEPTIONS=1)
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
add_definitions(-DBOOST_NO_EXCEPTIONS)
add_definitions(-DJSON_USE_EXCEPTION=0)
add_definitions(-DVALIJSON_USE_EXCEPTIONS=0)
endif()
find_package(curlpp)
find_package(Poco OPTIONAL_COMPONENTS JSON)
find_package(Qt5Core)

View File

@ -17,6 +17,7 @@
# include <functional>
# include <string>
# include <stdexcept>
# include <valijson/exceptions.hpp>
# define TR2_OPTIONAL_REQUIRES(...) typename enable_if<__VA_ARGS__::value, bool>::type = false
@ -523,15 +524,15 @@ namespace std{
}
constexpr T const& value() const& {
return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
return initialized() ? contained_val() : (valijson::throwRuntimeError("bad optional access"), contained_val());
}
OPTIONAL_MUTABLE_CONSTEXPR T& value() & {
return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
return initialized() ? contained_val() : (valijson::throwRuntimeError("bad optional access"), contained_val());
}
OPTIONAL_MUTABLE_CONSTEXPR T&& value() && {
if (!initialized()) throw bad_optional_access("bad optional access");
if (!initialized()) valijson::throwRuntimeError("bad optional access");
return std::move(contained_val());
}
@ -552,11 +553,11 @@ namespace std{
}
constexpr T const& value() const {
return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
return initialized() ? contained_val() : (valijson::throwRuntimeError("bad optional access"), contained_val());
}
T& value() {
return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
return initialized() ? contained_val() : (valijson::throwRuntimeError("bad optional access"), contained_val());
}
# endif
@ -685,7 +686,7 @@ namespace std{
}
constexpr T& value() const {
return ref ? *ref : (throw bad_optional_access("bad optional access"), *ref);
return ref ? *ref : (valijson::throwRuntimeError("bad optional access"), *ref);
}
explicit constexpr operator bool() const noexcept {

View File

@ -5,6 +5,7 @@
#include <valijson/adapters/adapter.hpp>
#include <valijson/internal/optional.hpp>
#include <valijson/exceptions.hpp>
namespace valijson {
namespace adapters {
@ -297,7 +298,7 @@ public:
}
}
throw std::runtime_error("JSON value cannot be cast to an array.");
throwRuntimeError("JSON value cannot be cast to an array.");
}
bool asBool() const override
@ -307,7 +308,7 @@ public:
return result;
}
throw std::runtime_error("JSON value cannot be cast to a boolean.");
throwRuntimeError("JSON value cannot be cast to a boolean.");
}
bool asBool(bool &result) const override
@ -337,7 +338,7 @@ public:
return result;
}
throw std::runtime_error("JSON value cannot be cast to a double.");
throwRuntimeError("JSON value cannot be cast to a double.");
}
bool asDouble(double &result) const override
@ -374,7 +375,7 @@ public:
return result;
}
throw std::runtime_error("JSON value cannot be cast as an integer.");
throwRuntimeError("JSON value cannot be cast as an integer.");
}
bool asInteger(int64_t &result) const override
@ -425,7 +426,7 @@ public:
}
}
throw std::runtime_error("JSON value cannot be cast to an object.");
throwRuntimeError("JSON value cannot be cast to an object.");
}
std::string asString() const override
@ -435,7 +436,7 @@ public:
return result;
}
throw std::runtime_error("JSON value cannot be cast to a string.");
throwRuntimeError("JSON value cannot be cast to a string.");
}
bool asString(std::string &result) const override
@ -541,7 +542,7 @@ public:
return *arrayValue;
}
throw std::runtime_error("JSON value is not an array.");
throwRuntimeError("JSON value is not an array.");
}
size_t getArraySize() const override
@ -551,7 +552,7 @@ public:
return result;
}
throw std::runtime_error("JSON value is not an array.");
throwRuntimeError("JSON value is not an array.");
}
bool getArraySize(size_t &result) const override
@ -566,7 +567,7 @@ public:
return result;
}
throw std::runtime_error("JSON value is not a boolean.");
throwRuntimeError("JSON value is not a boolean.");
}
bool getBool(bool &result) const override
@ -581,7 +582,7 @@ public:
return result;
}
throw std::runtime_error("JSON value is not a double.");
throwRuntimeError("JSON value is not a double.");
}
bool getDouble(double &result) const override
@ -596,7 +597,7 @@ public:
return result;
}
throw std::runtime_error("JSON value is not an integer.");
throwRuntimeError("JSON value is not an integer.");
}
bool getInteger(int64_t &result) const override
@ -611,7 +612,7 @@ public:
return result;
}
throw std::runtime_error("JSON value is not a number.");
throwRuntimeError("JSON value is not a number.");
}
bool getNumber(double &result) const override
@ -650,7 +651,7 @@ public:
return *objectValue;
}
throw std::runtime_error("JSON value is not an object.");
throwRuntimeError("JSON value is not an object.");
}
size_t getObjectSize() const override
@ -660,7 +661,7 @@ public:
return result;
}
throw std::runtime_error("JSON value is not an object.");
throwRuntimeError("JSON value is not an object.");
}
bool getObjectSize(size_t &result) const override
@ -675,7 +676,7 @@ public:
return result;
}
throw std::runtime_error("JSON value is not a string.");
throwRuntimeError("JSON value is not a string.");
}
bool getString(std::string &result) const override

View File

@ -31,6 +31,7 @@
#include <valijson/adapters/adapter.hpp>
#include <valijson/adapters/basic_adapter.hpp>
#include <valijson/adapters/frozen_value.hpp>
#include <valijson/exceptions.hpp>
namespace valijson {
namespace adapters {
@ -76,7 +77,7 @@ public:
: m_value(value)
{
if (!value.is_array()) {
throw std::runtime_error("Value is not an array.");
throwRuntimeError("Value is not an array.");
}
}
@ -154,7 +155,7 @@ public:
: m_value(value)
{
if (!value.is_object()) {
throw std::runtime_error("Value is not an object.");
throwRuntimeError("Value is not an object.");
}
}

View File

@ -34,6 +34,7 @@
#include <valijson/adapters/adapter.hpp>
#include <valijson/adapters/basic_adapter.hpp>
#include <valijson/adapters/frozen_value.hpp>
#include <valijson/exceptions.hpp>
namespace valijson {
namespace adapters {
@ -78,7 +79,7 @@ public:
: m_value(value)
{
if (!value.isArray()) {
throw std::runtime_error("Value is not an array.");
throwRuntimeError("Value is not an array.");
}
}
@ -156,7 +157,7 @@ public:
: m_value(value)
{
if (!value.isObject()) {
throw std::runtime_error("Value is not an object.");
throwRuntimeError("Value is not an object.");
}
}

View File

@ -31,6 +31,7 @@
#include <valijson/adapters/adapter.hpp>
#include <valijson/adapters/basic_adapter.hpp>
#include <valijson/adapters/frozen_value.hpp>
#include <valijson/exceptions.hpp>
#include <utility>
namespace valijson {
@ -77,7 +78,7 @@ public:
: m_value(value)
{
if (!value.is_array()) {
throw std::runtime_error("Value is not an array.");
throwRuntimeError("Value is not an array.");
}
}
@ -155,7 +156,7 @@ public:
: m_value(value)
{
if (!value.is_object()) {
throw std::runtime_error("Value is not an object.");
throwRuntimeError("Value is not an object.");
}
}

View File

@ -32,6 +32,7 @@
#include <valijson/adapters/adapter.hpp>
#include <valijson/adapters/basic_adapter.hpp>
#include <valijson/adapters/frozen_value.hpp>
#include <valijson/exceptions.hpp>
namespace valijson {
namespace adapters {
@ -77,7 +78,7 @@ public:
: m_value(value)
{
if (!value.is<picojson::array>()) {
throw std::runtime_error("Value is not an array.");
throwRuntimeError("Value is not an array.");
}
}
@ -156,7 +157,7 @@ public:
: m_value(value)
{
if (!value.is<picojson::object>()) {
throw std::runtime_error("Value is not an object.");
throwRuntimeError("Value is not an object.");
}
}

View File

@ -31,6 +31,7 @@
#include <valijson/adapters/adapter.hpp>
#include <valijson/adapters/basic_adapter.hpp>
#include <valijson/adapters/frozen_value.hpp>
#include <valijson/exceptions.hpp>
namespace valijson {
namespace adapters {
@ -77,7 +78,7 @@ public:
: m_value(value)
{
if (value.type() != typeid(Poco::JSON::Array::Ptr)) {
throw std::runtime_error("Value is not an array.");
throwRuntimeError("Value is not an array.");
}
}
@ -154,7 +155,7 @@ public:
: m_value(value)
{
if (value.type() != typeid(Poco::JSON::Object::Ptr)) {
throw std::runtime_error("Value is not an object.");
throwRuntimeError("Value is not an object.");
}
}

View File

@ -26,6 +26,7 @@
#pragma once
#include <string>
#include <utility>
#include <QJsonObject>
#include <QJsonValue>
@ -34,7 +35,7 @@
#include <valijson/adapters/adapter.hpp>
#include <valijson/adapters/basic_adapter.hpp>
#include <valijson/adapters/frozen_value.hpp>
#include <utility>
#include <valijson/exceptions.hpp>
namespace valijson {
namespace adapters {
@ -82,7 +83,7 @@ public:
: m_value(value.toArray())
{
if (!value.isArray()) {
throw std::runtime_error("Value is not an array.");
throwRuntimeError("Value is not an array.");
}
}
@ -162,7 +163,7 @@ public:
: m_value(value.toObject())
{
if (!value.isObject()) {
throw std::runtime_error("Value is not an object.");
throwRuntimeError("Value is not an object.");
}
}

View File

@ -48,6 +48,7 @@
#include <valijson/adapters/adapter.hpp>
#include <valijson/adapters/basic_adapter.hpp>
#include <valijson/adapters/frozen_value.hpp>
#include <valijson/exceptions.hpp>
namespace valijson {
namespace adapters {
@ -112,7 +113,7 @@ public:
: m_value(value)
{
if (!value.IsArray()) {
throw std::runtime_error("Value is not an array.");
throwRuntimeError("Value is not an array.");
}
}
@ -181,7 +182,7 @@ public:
: m_value(value)
{
if (!value.IsObject()) {
throw std::runtime_error("Value is not an object.");
throwRuntimeError("Value is not an object.");
}
}
@ -270,7 +271,7 @@ public:
explicit GenericRapidJsonFrozenValue(const ValueType &source)
{
if (!copy(source, m_value, m_allocator)) {
throw std::runtime_error("Failed to copy ValueType");
throwRuntimeError("Failed to copy ValueType");
}
}

View File

@ -19,6 +19,7 @@
#include <valijson/adapters/adapter.hpp>
#include <valijson/adapters/frozen_value.hpp>
#include <valijson/adapters/basic_adapter.hpp>
#include <valijson/exceptions.hpp>
namespace valijson {
namespace adapters {
@ -110,7 +111,7 @@ public:
return {};
}
throw std::runtime_error("String value cannot be cast to array");
throwRuntimeError("String value cannot be cast to array");
}
bool asBool() const override
@ -152,7 +153,7 @@ public:
return {};
}
throw std::runtime_error("String value cannot be cast to object");
throwRuntimeError("String value cannot be cast to object");
}
std::string asString() const override
@ -182,67 +183,67 @@ public:
static StdStringArray getArray()
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
size_t getArraySize() const override
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
bool getArraySize(size_t &) const override
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
bool getBool() const override
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
bool getBool(bool &) const override
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
double getDouble() const override
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
bool getDouble(double &) const override
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
int64_t getInteger() const override
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
bool getInteger(int64_t &) const override
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
double getNumber() const override
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
bool getNumber(double &) const override
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
size_t getObjectSize() const override
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
bool getObjectSize(size_t &) const override
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
std::string getString() const override
@ -355,12 +356,12 @@ class StdStringArrayValueIterator: public std::iterator<std::bidirectional_itera
public:
StdStringAdapter operator*() const
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
DerefProxy<StdStringAdapter> operator->() const
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
bool operator==(const StdStringArrayValueIterator &) const
@ -375,22 +376,22 @@ public:
const StdStringArrayValueIterator& operator++()
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
StdStringArrayValueIterator operator++(int)
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
const StdStringArrayValueIterator& operator--()
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
void advance(std::ptrdiff_t)
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
};
@ -409,12 +410,12 @@ class StdStringObjectMemberIterator: public std::iterator<std::bidirectional_ite
public:
StdStringObjectMember operator*() const
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
DerefProxy<StdStringObjectMember> operator->() const
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
bool operator==(const StdStringObjectMemberIterator &) const
@ -429,17 +430,17 @@ public:
const StdStringObjectMemberIterator& operator++()
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
StdStringObjectMemberIterator operator++(int)
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
const StdStringObjectMemberIterator& operator--()
{
throw std::runtime_error("Not supported");
throwNotSupported();
}
};

View File

@ -2,8 +2,8 @@
#include <valijson/constraints/constraint.hpp>
#include <valijson/constraints/constraint_visitor.hpp>
#include <valijson/internal/custom_allocator.hpp>
#include <valijson/exceptions.hpp>
namespace valijson {
namespace constraints {
@ -40,7 +40,7 @@ struct BasicConstraint: Constraint
{
void *ptr = allocFn(sizeof(ConstraintType));
if (!ptr) {
throw std::runtime_error("Failed to allocate memory for cloned constraint");
throwRuntimeError("Failed to allocate memory for cloned constraint");
}
return new (ptr) ConstraintType(*static_cast<const ConstraintType*>(this));

View File

@ -24,6 +24,7 @@
#include <valijson/constraints/basic_constraint.hpp>
#include <valijson/internal/custom_allocator.hpp>
#include <valijson/schema.hpp>
#include <valijson/exceptions.hpp>
namespace valijson {
@ -296,7 +297,7 @@ public:
return *this;
}
throw std::runtime_error("Dependencies constraint already contains a dependent "
throwRuntimeError("Dependencies constraint already contains a dependent "
"schema for the property '" + propertyName + "'");
}
@ -357,12 +358,17 @@ public:
: BasicConstraint(other),
m_enumValues(Allocator::rebind<const EnumValue *>::other(m_allocator))
{
#if VALIJSON_USE_EXCEPTIONS
try {
#endif
// Clone individual enum values
for (const EnumValue *otherValue : other.m_enumValues) {
const EnumValue *value = otherValue->clone();
#if VALIJSON_USE_EXCEPTIONS
try {
#endif
m_enumValues.push_back(value);
#if VALIJSON_USE_EXCEPTIONS
} catch (...) {
delete value;
value = nullptr;
@ -375,6 +381,7 @@ public:
delete value;
}
throw;
#endif
}
}
@ -895,15 +902,19 @@ public:
{
void *ptr = allocFn(sizeOf());
if (!ptr) {
throw std::runtime_error("Failed to allocate memory for cloned constraint");
throwRuntimeError("Failed to allocate memory for cloned constraint");
}
#if VALIJSON_USE_EXCEPTIONS
try {
#endif
return cloneInto(ptr);
#if VALIJSON_USE_EXCEPTIONS
} catch (...) {
freeFn(ptr);
throw;
}
#endif
}
virtual bool validate(const adapters::Adapter &target,
@ -1190,8 +1201,9 @@ public:
return kString;
}
throw std::runtime_error("Unrecognised JSON type name '" +
throwRuntimeError("Unrecognised JSON type name '" +
std::string(typeName.c_str()) + "'");
abort();
}
private:

View File

@ -0,0 +1,41 @@
#pragma once
#include <iostream>
#include <exception>
namespace valijson {
#if defined(_MSC_VER) && _MSC_VER == 1800
#define VALIJSON_NORETURN __declspec(noreturn)
#else
#define VALIJSON_NORETURN [[noreturn]]
#endif
#if VALIJSON_USE_EXCEPTIONS
#include <stdexcept>
VALIJSON_NORETURN inline void throwRuntimeError(const std::string& msg) {
throw std::runtime_error(msg);
}
VALIJSON_NORETURN inline void throwLogicError(const std::string& msg) {
throw std::logic_error(msg);
}
#else
VALIJSON_NORETURN inline void throwRuntimeError(const std::string& msg) {
std::cerr << msg << std::endl;
abort();
}
VALIJSON_NORETURN inline void throwLogicError(const std::string& msg) {
std::cerr << msg << std::endl;
abort();
}
#endif
VALIJSON_NORETURN inline void throwNotSupported() {
throwRuntimeError("Not supported"); \
}
} // namespace valijson

View File

@ -9,6 +9,7 @@
#include <valijson/adapters/adapter.hpp>
#include <valijson/internal/optional.hpp>
#include <valijson/exceptions.hpp>
namespace valijson {
namespace internal {
@ -43,7 +44,7 @@ inline void replaceAllInPlace(std::string& subject, const char* search,
inline char decodePercentEncodedChar(const std::string &digits)
{
if (digits.length() != 2) {
throw std::runtime_error("Failed to decode %-encoded character '" +
throwRuntimeError("Failed to decode %-encoded character '" +
digits + "' due to unexpected number of characters; "
"expected two characters");
}
@ -53,7 +54,7 @@ inline char decodePercentEncodedChar(const std::string &digits)
char *end = nullptr;
const unsigned long value = strtoul(begin, &end, 16);
if (end != begin && *end != '\0') {
throw std::runtime_error("Failed to decode %-encoded character '" +
throwRuntimeError("Failed to decode %-encoded character '" +
digits + "'");
}
@ -101,14 +102,17 @@ inline std::string extractReferenceToken(std::string::const_iterator begin,
for (size_t n = token.find('%'); n != std::string::npos;
n = token.find('%', n + 1)) {
#if VALIJSON_USE_EXCEPTIONS
try {
#endif
const char c = decodePercentEncodedChar(token.substr(n + 1, 2));
token.replace(n, 3, &c, 1);
#if VALIJSON_USE_EXCEPTIONS
} catch (const std::runtime_error &e) {
throw std::runtime_error(
throwRuntimeError(
std::string(e.what()) + "; in token: " + token);
}
#endif
}
return token;
@ -159,7 +163,7 @@ inline AdapterType resolveJsonPointer(
// Reference tokens must begin with a leading slash
if (*jsonPointerItr != '/') {
throw std::runtime_error("Expected reference token to begin with "
throwRuntimeError("Expected reference token to begin with "
"leading slash; remaining tokens: " +
std::string(jsonPointerItr, jsonPointerEnd));
}
@ -179,24 +183,26 @@ inline AdapterType resolveJsonPointer(
} else if (node.isArray()) {
if (referenceToken == "-") {
throw std::runtime_error("Hyphens cannot be used as array indices "
throwRuntimeError("Hyphens cannot be used as array indices "
"since the requested array element does not yet exist");
}
#if VALIJSON_USE_EXCEPTIONS
try {
#endif
// Fragment must be non-negative integer
const uint64_t index = std::stoul(referenceToken);
typedef typename AdapterType::Array Array;
typename Array::const_iterator itr = node.asArray().begin();
if (index > node.asArray().size() - 1) {
throw std::runtime_error("Expected reference token to identify "
throwRuntimeError("Expected reference token to identify "
"an element in the current array, but array index is "
"out of bounds; actual token: " + referenceToken);
}
if (index > static_cast<uint64_t>(std::numeric_limits<std::ptrdiff_t>::max())) {
throw std::runtime_error("Array index out of bounds; hard "
throwRuntimeError("Array index out of bounds; hard "
"limit is " + std::to_string(
std::numeric_limits<std::ptrdiff_t>::max()));
}
@ -206,12 +212,13 @@ inline AdapterType resolveJsonPointer(
// Recursively process the remaining tokens
return resolveJsonPointer(*itr, jsonPointer, jsonPointerNext);
#if VALIJSON_USE_EXCEPTIONS
} catch (std::invalid_argument &) {
throw std::runtime_error("Expected reference token to contain a "
throwRuntimeError("Expected reference token to contain a "
"non-negative integer to identify an element in the "
"current array; actual token: " + referenceToken);
}
#endif
} else if (node.maybeObject()) {
// Fragment must identify a member of the candidate object
typedef typename AdapterType::Object Object;
@ -220,18 +227,20 @@ inline AdapterType resolveJsonPointer(
typename Object::const_iterator itr = object.find(
referenceToken);
if (itr == object.end()) {
throw std::runtime_error("Expected reference token to identify an "
throwRuntimeError("Expected reference token to identify an "
"element in the current object; "
"actual token: " + referenceToken);
abort();
}
// Recursively process the remaining tokens
return resolveJsonPointer(itr->second, jsonPointer, jsonPointerNext);
}
throw std::runtime_error("Expected end of JSON Pointer, but at least "
throwRuntimeError("Expected end of JSON Pointer, but at least "
"one reference token has not been processed; remaining tokens: " +
std::string(jsonPointerNext, jsonPointerEnd));
abort();
}
/**

View File

@ -4,6 +4,7 @@
#include <set>
#include <valijson/subschema.hpp>
#include <valijson/exceptions.hpp>
namespace valijson {
@ -53,15 +54,19 @@ public:
m_freeFn(const_cast<Subschema *>(sharedEmptySubschema));
sharedEmptySubschema = nullptr;
#if VALIJSON_USE_EXCEPTIONS
try {
#endif
for (auto subschema : subschemaSet) {
subschema->~Subschema();
m_freeFn(subschema);
}
#if VALIJSON_USE_EXCEPTIONS
} catch (const std::exception &e) {
fprintf(stderr, "Caught an exception while destroying Schema: %s",
e.what());
}
#endif
}
/**
@ -92,17 +97,20 @@ public:
{
Subschema *subschema = newSubschema();
#if VALIJSON_USE_EXCEPTIONS
try {
#endif
if (!subschemaSet.insert(subschema).second) {
throw std::runtime_error(
throwRuntimeError(
"Failed to store pointer for new sub-schema");
}
#if VALIJSON_USE_EXCEPTIONS
} catch (...) {
subschema->~Subschema();
m_freeFn(subschema);
throw;
}
#endif
return subschema;
}
@ -170,16 +178,20 @@ private:
{
void *ptr = m_allocFn(sizeof(Subschema));
if (!ptr) {
throw std::runtime_error(
throwRuntimeError(
"Failed to allocate memory for shared empty sub-schema");
}
#if VALIJSON_USE_EXCEPTIONS
try {
#endif
return new (ptr) Subschema();
#if VALIJSON_USE_EXCEPTIONS
} catch (...) {
m_freeFn(ptr);
throw;
}
#endif
}
Subschema * mutableSubschema(const Subschema *subschema)
@ -189,13 +201,13 @@ private:
}
if (subschema == sharedEmptySubschema) {
throw std::runtime_error(
throwRuntimeError(
"Cannot modify the shared empty sub-schema");
}
auto *noConst = const_cast<Subschema*>(subschema);
if (subschemaSet.find(noConst) == subschemaSet.end()) {
throw std::runtime_error(
throwRuntimeError(
"Subschema pointer is not owned by this Schema instance");
}

View File

@ -14,6 +14,7 @@
#include <valijson/internal/uri.hpp>
#include <valijson/constraint_builder.hpp>
#include <valijson/schema.hpp>
#include <valijson/exceptions.hpp>
#ifdef __clang__
# pragma clang diagnostic push
@ -117,18 +118,22 @@ public:
typename FunctionPtrs<AdapterType>::FreeDoc freeDoc = nullptr )
{
if ((fetchDoc == nullptr ) ^ (freeDoc == nullptr)) {
throw std::runtime_error("Remote document fetching can't be enabled without both fetch and free functions");
throwRuntimeError("Remote document fetching can't be enabled without both fetch and free functions");
}
typename DocumentCache<AdapterType>::Type docCache;
SchemaCache schemaCache;
#if VALIJSON_USE_EXCEPTIONS
try {
#endif
resolveThenPopulateSchema(schema, node, node, schema, opt::optional<std::string>(), "", fetchDoc, nullptr,
nullptr, docCache, schemaCache);
#if VALIJSON_USE_EXCEPTIONS
} catch (...) {
freeDocumentCache<AdapterType>(docCache, freeDoc);
throw;
}
#endif
freeDocumentCache<AdapterType>(docCache, freeDoc);
}
@ -238,7 +243,7 @@ private:
if (itr == o.end()) {
return false;
} else if (!itr->second.asString(result)) {
throw std::invalid_argument("$ref property expected to contain string value.");
throwRuntimeError("$ref property expected to contain string value.");
}
return true;
@ -306,7 +311,7 @@ private:
for (const std::string &keyToCreate : keysToCreate) {
const SchemaCache::value_type value(keyToCreate, schema);
if (!schemaCache.insert(value).second) {
throw std::logic_error("Key '" + keyToCreate + "' already in schema cache.");
throwLogicError("Key '" + keyToCreate + "' already in schema cache.");
}
}
}
@ -423,7 +428,7 @@ private:
if (docCacheItr == docCache.end()) {
// Resolve reference against remote document
if (!fetchDoc) {
throw std::runtime_error("Fetching of remote JSON References not enabled.");
throwRuntimeError("Fetching of remote JSON References not enabled.");
}
// Returns a pointer to the remote document that was
@ -434,7 +439,7 @@ private:
// Can't proceed without the remote document
if (!newDoc) {
throw std::runtime_error("Failed to fetch referenced schema document: " + *actualDocumentUri);
throwRuntimeError("Failed to fetch referenced schema document: " + *actualDocumentUri);
}
typedef typename DocumentCache<AdapterType>::Type::value_type
@ -588,7 +593,7 @@ private:
s += " to contain schema object; actual node type is: ";
}
s += internal::nodeTypeAsString(node);
throw std::runtime_error(s);
throwRuntimeError(s);
}
}
@ -650,7 +655,7 @@ private:
rootSchema.setSubschemaDescription(&subschema,
itr->second.asString());
} else {
throw std::runtime_error(
throwRuntimeError(
"'description' attribute should have a string value");
}
}
@ -666,11 +671,11 @@ private:
makeMultipleOfDoubleConstraint(itr->second),
&subschema);
} else {
throw std::runtime_error("Expected an numeric value for "
throwRuntimeError("Expected an numeric value for "
" 'divisibleBy' constraint.");
}
} else {
throw std::runtime_error(
throwRuntimeError(
"'divisibleBy' constraint not valid after draft 3");
}
}
@ -722,7 +727,7 @@ private:
updatedScope, nodePath, fetchDoc, docCache, schemaCache),
&subschema);
} else {
throw std::runtime_error("Not supported");
throwRuntimeError("Not supported");
}
}
}
@ -752,7 +757,7 @@ private:
&subschema);
}
} else if (object.find("exclusiveMaximum") != object.end()) {
throw std::runtime_error("'exclusiveMaximum' constraint only valid if a 'maximum' "
throwRuntimeError("'exclusiveMaximum' constraint only valid if a 'maximum' "
"constraint is also present");
}
@ -794,7 +799,7 @@ private:
&subschema);
}
} else if (object.find("exclusiveMinimum") != object.end()) {
throw std::runtime_error("'exclusiveMinimum' constraint only valid if a 'minimum' "
throwRuntimeError("'exclusiveMinimum' constraint only valid if a 'minimum' "
"constraint is also present");
}
@ -815,7 +820,7 @@ private:
if ((itr = object.find("multipleOf")) != object.end()) {
if (m_version == kDraft3) {
throw std::runtime_error("'multipleOf' constraint not available in draft 3");
throwRuntimeError("'multipleOf' constraint not available in draft 3");
} else if (itr->second.maybeInteger()) {
rootSchema.addConstraintToSubschema(
makeMultipleOfIntConstraint(itr->second),
@ -825,7 +830,7 @@ private:
makeMultipleOfDoubleConstraint(itr->second),
&subschema);
} else {
throw std::runtime_error("Expected an numeric value for 'divisibleBy' constraint.");
throwRuntimeError("Expected an numeric value for 'divisibleBy' constraint.");
}
}
@ -878,7 +883,7 @@ private:
nodePath, fetchDoc, docCache, schemaCache),
&subschema);
} else {
throw std::runtime_error("Not supported");
throwRuntimeError("Not supported");
}
}
@ -891,7 +896,7 @@ private:
rootSchema.addConstraintToSubschema(*constraint, parentSubschema);
}
} else {
throw std::runtime_error("'required' constraint not valid here");
throwRuntimeError("'required' constraint not valid here");
}
} else {
rootSchema.addConstraintToSubschema(makeRequiredConstraint(itr->second), &subschema);
@ -902,7 +907,7 @@ private:
if (itr->second.maybeString()) {
rootSchema.setSubschemaTitle(&subschema, itr->second.asString());
} else {
throw std::runtime_error("'title' attribute should have a string value");
throwRuntimeError("'title' attribute should have a string value");
}
}
@ -923,14 +928,18 @@ private:
for (const auto & constraintBuilder : constraintBuilders) {
if ((itr = object.find(constraintBuilder.first)) != object.end()) {
constraints::Constraint *constraint = nullptr;
#if VALIJSON_USE_EXCEPTIONS
try {
#endif
constraint = constraintBuilder.second->make(itr->second);
rootSchema.addConstraintToSubschema(*constraint, &subschema);
delete constraint;
#if VALIJSON_USE_EXCEPTIONS
} catch (...) {
delete constraint;
throw;
}
#endif
}
}
}
@ -992,14 +1001,14 @@ private:
if (documentUri && internal::uri::isUriAbsolute(*documentUri)) {
// Resolve reference against remote document
if (!fetchDoc) {
throw std::runtime_error("Fetching of remote JSON References not enabled.");
throwRuntimeError("Fetching of remote JSON References not enabled.");
}
const typename DocumentCache<AdapterType>::DocumentType *newDoc = fetchDoc(*documentUri);
// Can't proceed without the remote document
if (!newDoc) {
throw std::runtime_error("Failed to fetch referenced schema document: " + *documentUri);
throwRuntimeError("Failed to fetch referenced schema document: " + *documentUri);
}
// Add to document cache
@ -1056,7 +1065,7 @@ private:
SchemaCache &schemaCache)
{
if (!node.maybeArray()) {
throw std::runtime_error("Expected array value for 'allOf' constraint.");
throwRuntimeError("Expected array value for 'allOf' constraint.");
}
constraints::AllOfConstraint constraint;
@ -1071,7 +1080,7 @@ private:
constraint.addSubschema(subschema);
index++;
} else {
throw std::runtime_error("Expected element to be a valid schema in 'allOf' constraint.");
throwRuntimeError("Expected element to be a valid schema in 'allOf' constraint.");
}
}
@ -1108,7 +1117,7 @@ private:
SchemaCache &schemaCache)
{
if (!node.maybeArray()) {
throw std::runtime_error("Expected array value for 'anyOf' constraint.");
throwRuntimeError("Expected array value for 'anyOf' constraint.");
}
constraints::AnyOfConstraint constraint;
@ -1123,7 +1132,7 @@ private:
constraint.addSubschema(subschema);
index++;
} else {
throw std::runtime_error("Expected array element to be a valid schema in 'anyOf' constraint.");
throwRuntimeError("Expected array element to be a valid schema in 'anyOf' constraint.");
}
}
@ -1262,7 +1271,7 @@ private:
} else {
// All other formats will result in an exception being thrown.
throw std::runtime_error("Expected valid schema for 'contains' constraint.");
throwRuntimeError("Expected valid schema for 'contains' constraint.");
}
return constraint;
@ -1316,7 +1325,7 @@ private:
SchemaCache &schemaCache)
{
if (!node.maybeObject()) {
throw std::runtime_error("Expected valid subschema for 'dependencies' constraint.");
throwRuntimeError("Expected valid subschema for 'dependencies' constraint.");
}
constraints::DependenciesConstraint dependenciesConstraint;
@ -1338,7 +1347,7 @@ private:
if (dependencyName.maybeString()) {
dependentPropertyNames.push_back(dependencyName.getString());
} else {
throw std::runtime_error("Expected string value in dependency list of property '" +
throwRuntimeError("Expected string value in dependency list of property '" +
member.first + "' in 'dependencies' constraint.");
}
}
@ -1370,7 +1379,7 @@ private:
// All other types result in an exception being thrown.
} else {
throw std::runtime_error("Invalid dependencies definition.");
throwRuntimeError("Invalid dependencies definition.");
}
}
@ -1468,7 +1477,7 @@ private:
} else {
// Any other format for the additionalItems property will result
// in an exception being thrown.
throw std::runtime_error("Expected bool or object value for 'additionalItems'");
throwRuntimeError("Expected bool or object value for 'additionalItems'");
}
} else {
// The default value for the additionalItems property is an empty
@ -1497,7 +1506,7 @@ private:
index++;
}
} else {
throw std::runtime_error("Expected array value for non-singular 'items' constraint.");
throwRuntimeError("Expected array value for non-singular 'items' constraint.");
}
}
@ -1567,7 +1576,7 @@ private:
} else {
// All other formats will result in an exception being thrown.
throw std::runtime_error("Expected valid schema for singular 'items' constraint.");
throwRuntimeError("Expected valid schema for singular 'items' constraint.");
}
return constraint;
@ -1596,7 +1605,7 @@ private:
const AdapterType *exclusiveMaximum)
{
if (!node.maybeDouble()) {
throw std::runtime_error("Expected numeric value for maximum constraint.");
throwRuntimeError("Expected numeric value for maximum constraint.");
}
constraints::MaximumConstraint constraint;
@ -1604,7 +1613,7 @@ private:
if (exclusiveMaximum) {
if (!exclusiveMaximum->maybeBool()) {
throw std::runtime_error("Expected boolean value for exclusiveMaximum constraint.");
throwRuntimeError("Expected boolean value for exclusiveMaximum constraint.");
}
constraint.setExclusiveMaximum(exclusiveMaximum->asBool());
@ -1627,7 +1636,7 @@ private:
constraints::MaximumConstraint makeMaximumConstraintExclusive(const AdapterType &node)
{
if (!node.maybeDouble()) {
throw std::runtime_error("Expected numeric value for maximum constraint.");
throwRuntimeError("Expected numeric value for maximum constraint.");
}
constraints::MaximumConstraint constraint;
@ -1657,7 +1666,7 @@ private:
}
}
throw std::runtime_error("Expected non-negative integer value for 'maxItems' constraint.");
throwRuntimeError("Expected non-negative integer value for 'maxItems' constraint.");
}
/**
@ -1681,7 +1690,7 @@ private:
}
}
throw std::runtime_error("Expected a non-negative integer value for 'maxLength' constraint.");
throwRuntimeError("Expected a non-negative integer value for 'maxLength' constraint.");
}
/**
@ -1707,7 +1716,7 @@ private:
}
}
throw std::runtime_error("Expected a non-negative integer for 'maxProperties' constraint.");
throwRuntimeError("Expected a non-negative integer for 'maxProperties' constraint.");
}
/**
@ -1728,7 +1737,7 @@ private:
const AdapterType *exclusiveMinimum)
{
if (!node.maybeDouble()) {
throw std::runtime_error("Expected numeric value for minimum constraint.");
throwRuntimeError("Expected numeric value for minimum constraint.");
}
constraints::MinimumConstraint constraint;
@ -1736,7 +1745,7 @@ private:
if (exclusiveMinimum) {
if (!exclusiveMinimum->maybeBool()) {
throw std::runtime_error("Expected boolean value for 'exclusiveMinimum' constraint.");
throwRuntimeError("Expected boolean value for 'exclusiveMinimum' constraint.");
}
constraint.setExclusiveMinimum(exclusiveMinimum->asBool());
@ -1759,7 +1768,7 @@ private:
constraints::MinimumConstraint makeMinimumConstraintExclusive(const AdapterType &node)
{
if (!node.maybeDouble()) {
throw std::runtime_error("Expected numeric value for minimum constraint.");
throwRuntimeError("Expected numeric value for minimum constraint.");
}
constraints::MinimumConstraint constraint;
@ -1788,7 +1797,7 @@ private:
}
}
throw std::runtime_error("Expected a non-negative integer value for 'minItems' constraint.");
throwRuntimeError("Expected a non-negative integer value for 'minItems' constraint.");
}
/**
@ -1811,7 +1820,7 @@ private:
}
}
throw std::runtime_error("Expected a non-negative integer value for 'minLength' constraint.");
throwRuntimeError("Expected a non-negative integer value for 'minLength' constraint.");
}
@ -1837,7 +1846,7 @@ private:
}
}
throw std::runtime_error("Expected a non-negative integer for 'minProperties' constraint.");
throwRuntimeError("Expected a non-negative integer for 'minProperties' constraint.");
}
/**
@ -1909,7 +1918,7 @@ private:
return constraint;
}
throw std::runtime_error("Expected object value for 'not' constraint.");
throwRuntimeError("Expected object value for 'not' constraint.");
}
/**
@ -2081,7 +2090,7 @@ private:
constraint.setAdditionalPropertiesSubschema(subschema);
} else {
// All other types are invalid
throw std::runtime_error("Invalid type for 'additionalProperties' constraint.");
throwRuntimeError("Invalid type for 'additionalProperties' constraint.");
}
} else {
// If an additionalProperties constraint is not provided, then the
@ -2128,7 +2137,7 @@ private:
const std::string &name)
{
if (!node.maybeBool()) {
throw std::runtime_error("Expected boolean value for 'required' attribute.");
throwRuntimeError("Expected boolean value for 'required' attribute.");
}
if (node.asBool()) {
@ -2159,7 +2168,7 @@ private:
for (const AdapterType v : node.getArray()) {
if (!v.maybeString()) {
throw std::runtime_error("Expected required property name to be a string value");
throwRuntimeError("Expected required property name to be a string value");
}
constraint.addRequiredProperty(v.getString());
@ -2203,7 +2212,7 @@ private:
if (node.maybeString()) {
const TypeConstraint::JsonType type = TypeConstraint::jsonTypeFromString(node.getString());
if (type == TypeConstraint::kAny && m_version == kDraft4) {
throw std::runtime_error("'any' type is not supported in version 4 schemas.");
throwRuntimeError("'any' type is not supported in version 4 schemas.");
}
constraint.addNamedType(type);
@ -2214,7 +2223,7 @@ private:
if (v.maybeString()) {
const TypeConstraint::JsonType type = TypeConstraint::jsonTypeFromString(v.getString());
if (type == TypeConstraint::kAny && m_version == kDraft4) {
throw std::runtime_error("'any' type is not supported in version 4 schemas.");
throwRuntimeError("'any' type is not supported in version 4 schemas.");
}
constraint.addNamedType(type);
@ -2226,7 +2235,7 @@ private:
constraint.addSchemaType(subschema);
} else {
throw std::runtime_error("Type name should be a string.");
throwRuntimeError("Type name should be a string.");
}
index++;
@ -2238,7 +2247,7 @@ private:
constraint.addSchemaType(subschema);
} else {
throw std::runtime_error("Type name should be a string.");
throwRuntimeError("Type name should be a string.");
}
return constraint;
@ -2266,7 +2275,7 @@ private:
}
}
throw std::runtime_error("Expected boolean value for 'uniqueItems' constraint.");
throwRuntimeError("Expected boolean value for 'uniqueItems' constraint.");
}
private:

View File

@ -6,6 +6,7 @@
#include <valijson/constraints/constraint.hpp>
#include <valijson/internal/optional.hpp>
#include <valijson/exceptions.hpp>
namespace valijson {
@ -69,17 +70,21 @@ public:
*/
virtual ~Subschema()
{
#if VALIJSON_USE_EXCEPTIONS
try {
#endif
for (auto constConstraint : m_constraints) {
auto *constraint = const_cast<Constraint *>(constConstraint);
constraint->~Constraint();
m_freeFn(constraint);
}
m_constraints.clear();
#if VALIJSON_USE_EXCEPTIONS
} catch (const std::exception &e) {
fprintf(stderr, "Caught an exception in Subschema destructor: %s",
e.what());
}
#endif
}
/**
@ -96,13 +101,17 @@ public:
void addConstraint(const Constraint &constraint)
{
Constraint *newConstraint = constraint.clone(m_allocFn, m_freeFn);
#if VALIJSON_USE_EXCEPTIONS
try {
#endif
m_constraints.push_back(newConstraint);
#if VALIJSON_USE_EXCEPTIONS
} catch (...) {
newConstraint->~Constraint();
m_freeFn(newConstraint);
throw;
}
#endif
}
/**
@ -165,7 +174,7 @@ public:
return *m_description;
}
throw std::runtime_error("Schema does not have a description");
throwRuntimeError("Schema does not have a description");
}
/**
@ -181,7 +190,7 @@ public:
return *m_id;
}
throw std::runtime_error("Schema does not have an ID");
throwRuntimeError("Schema does not have an ID");
}
/**
@ -197,7 +206,7 @@ public:
return *m_title;
}
throw std::runtime_error("Schema does not have a title");
throwRuntimeError("Schema does not have a title");
}
/**

View File

@ -4,6 +4,7 @@
#include <json.hpp>
#include <valijson/utils/file_utils.hpp>
#include <valijson/exceptions.hpp>
namespace valijson {
namespace utils {
@ -19,6 +20,7 @@ inline bool loadDocument(const std::string &path, nlohmann::json &document)
}
// Parse schema
#if VALIJSON_USE_EXCEPTION
try {
document = nlohmann::json::parse(file);
} catch (std::invalid_argument const& exception) {
@ -26,6 +28,13 @@ inline bool loadDocument(const std::string &path, nlohmann::json &document)
<< "Parse error:" << exception.what() << "\n";
return false;
}
#else
document = nlohmann::json::parse(file, nullptr, false);
if (document.is_discarded()) {
std::cerr << "nlohmann::json failed to parse the document.";
return false;
}
#endif
return true;
}

View File

@ -4,6 +4,7 @@
#include <sstream>
#include <boost/property_tree/ptree.hpp>
#include <boost/throw_exception.hpp>
#if defined(__clang__)
# pragma clang diagnostic push
@ -14,20 +15,57 @@
# include <boost/property_tree/json_parser.hpp>
#endif
// Source locations were added in boost 1.73.
#include <boost/version.hpp>
#if (BOOST_VERSION > 107300)
#include <boost/assert/source_location.hpp>
#endif
#include <valijson/utils/file_utils.hpp>
#include <valijson/exceptions.hpp>
#if !VALIJSON_USE_EXCEPTION
namespace boost {
// Boost requires used-defined exception throwers when exceptions are
// disabled.
// NOTE: BOOST_NORETURN attribute was added in 1.71.
#if (BOOST_VERSION >= 107100)
BOOST_NORETURN
#endif
void throw_exception(std::exception const & e ) {
valijson::throwRuntimeError(e.what());
}
// Source location override was added in 1.73.
#if (BOOST_VERSION >= 107300)
BOOST_NORETURN
void throw_exception(std::exception const & e, boost::source_location const & loc ) {
valijson::throwRuntimeError(e.what());
}
#endif
} // namespace boost
#endif
namespace valijson {
namespace utils {
inline bool loadDocument(const std::string &path, boost::property_tree::ptree &document)
{
#if !defined(BOOST_NO_EXCEPTIONS)
try {
#endif
boost::property_tree::read_json(path, document);
#if !defined(BOOST_NO_EXCEPTIONS)
} catch (std::exception &e) {
std::cerr << "Boost Property Tree JSON parser failed to parse the document:" << std::endl;
std::cerr << e.what() << std::endl;
return false;
}
#endif
return true;
}

View File

@ -1,6 +1,10 @@
#pragma once
#include <assert.h>
#include <stdexcept>
#include <string>
#include <valijson/exceptions.hpp>
/*
Basic UTF-8 manipulation routines, adapted from code that was released into
@ -21,14 +25,14 @@ inline bool isutf(char c) {
}
/* reads the next utf-8 sequence out of a string, updating an index */
inline uint32_t u8_nextchar(const char *s, int *i)
inline uint64_t u8_nextchar(const char *s, uint64_t *i)
{
uint32_t ch = 0;
uint64_t ch = 0;
int sz = 0;
do {
ch <<= 6;
ch += (unsigned char)s[(*i)++];
ch += static_cast<unsigned char>(s[(*i)++]);
sz++;
} while (s[*i] && !isutf(s[*i]));
ch -= offsetsFromUTF8[sz-1];
@ -39,14 +43,13 @@ inline uint32_t u8_nextchar(const char *s, int *i)
/* number of characters */
inline uint64_t u8_strlen(const char *s)
{
static const int maxLength = std::numeric_limits<int>::max();
constexpr auto maxLength = std::numeric_limits<uint64_t>::max();
uint64_t count = 0;
int i = 0;
uint64_t i = 0;
while (s[i] != 0 && u8_nextchar(s, &i) != 0) {
if (i == maxLength) {
throw std::runtime_error(
throwRuntimeError(
"String exceeded maximum size of " +
std::to_string(maxLength) + " bytes.");
}

View File

@ -22,12 +22,13 @@ TEST_F(TestJson11Adapter, BasicArrayIteration)
// Ensure that wrapping the document preserves the array and does not allow
// it to be cast to other types
valijson::adapters::Json11Adapter adapter(document);
#if VALIJSON_USE_EXCEPTIONS
ASSERT_NO_THROW( adapter.getArray() );
ASSERT_ANY_THROW( adapter.getBool() );
ASSERT_ANY_THROW( adapter.getDouble() );
ASSERT_ANY_THROW( adapter.getObject() );
ASSERT_ANY_THROW( adapter.getString() );
#endif
// Ensure that the array contains the expected number of elements
EXPECT_EQ( numElements, adapter.getArray().size() );
@ -59,12 +60,13 @@ TEST_F(TestJson11Adapter, BasicObjectIteration)
// Ensure that wrapping the document preserves the object and does not
// allow it to be cast to other types
valijson::adapters::Json11Adapter adapter(document);
#if VALIJSON_USE_EXCEPTIONS
ASSERT_NO_THROW( adapter.getObject() );
ASSERT_ANY_THROW( adapter.getArray() );
ASSERT_ANY_THROW( adapter.getBool() );
ASSERT_ANY_THROW( adapter.getDouble() );
ASSERT_ANY_THROW( adapter.getString() );
#endif
// Ensure that the object contains the expected number of members
EXPECT_EQ( numElements, adapter.getObject().size() );

View File

@ -298,7 +298,12 @@ TEST_F(TestJsonPointer, JsonPointerTestCases)
const RapidJsonAdapter actualAdapter = resolveJsonPointer(valueAdapter, jsonPointer);
EXPECT_TRUE(actualAdapter.equalTo(expectedAdapter, true)) << testCase->description;
} else {
// Since the tests with throwing disabled will abort, we can't
// do anything here.
#if VALIJSON_USE_EXCEPTIONS
EXPECT_THROW(resolveJsonPointer(valueAdapter, jsonPointer), std::runtime_error) << testCase->description;
#endif
}
}
}

View File

@ -21,12 +21,13 @@ TEST_F(TestJsonCppAdapter, BasicArrayIteration)
// Ensure that wrapping the document preserves the array and does not allow
// it to be cast to other types
valijson::adapters::JsonCppAdapter adapter(document);
#if VALIJSON_USE_EXCEPTIONS
ASSERT_NO_THROW( adapter.getArray() );
ASSERT_ANY_THROW( adapter.getBool() );
ASSERT_ANY_THROW( adapter.getDouble() );
ASSERT_ANY_THROW( adapter.getObject() );
ASSERT_ANY_THROW( adapter.getString() );
#endif
// Ensure that the array contains the expected number of elements
EXPECT_EQ( numElements, adapter.getArray().size() );
@ -57,11 +58,13 @@ TEST_F(TestJsonCppAdapter, BasicObjectIteration)
// Ensure that wrapping the document preserves the object and does not
// allow it to be cast to other types
valijson::adapters::JsonCppAdapter adapter(document);
#if VALIJSON_USE_EXCEPTIONS
ASSERT_NO_THROW( adapter.getObject() );
ASSERT_ANY_THROW( adapter.getArray() );
ASSERT_ANY_THROW( adapter.getBool() );
ASSERT_ANY_THROW( adapter.getDouble() );
ASSERT_ANY_THROW( adapter.getString() );
#endif
// Ensure that the object contains the expected number of members
EXPECT_EQ( numElements, adapter.getObject().size() );

View File

@ -21,11 +21,13 @@ TEST_F(TestNlohmannJsonAdapter, BasicArrayIteration)
// Ensure that wrapping the document preserves the array and does not allow
// it to be cast to other types
valijson::adapters::NlohmannJsonAdapter adapter(document);
#if VALIJSON_USE_EXCEPTIONS
ASSERT_NO_THROW( adapter.getArray() );
ASSERT_ANY_THROW( adapter.getBool() );
ASSERT_ANY_THROW( adapter.getDouble() );
ASSERT_ANY_THROW( adapter.getObject() );
ASSERT_ANY_THROW( adapter.getString() );
#endif
// Ensure that the array contains the expected number of elements
EXPECT_EQ( numElements, adapter.getArray().size() );
@ -56,11 +58,13 @@ TEST_F(TestNlohmannJsonAdapter, BasicObjectIteration)
// Ensure that wrapping the document preserves the object and does not
// allow it to be cast to other types
valijson::adapters::NlohmannJsonAdapter adapter(document);
#if VALIJSON_USE_EXCEPTIONS
ASSERT_NO_THROW( adapter.getObject() );
ASSERT_ANY_THROW( adapter.getArray() );
ASSERT_ANY_THROW( adapter.getBool() );
ASSERT_ANY_THROW( adapter.getDouble() );
ASSERT_ANY_THROW( adapter.getString() );
#endif
// Ensure that the object contains the expected number of members
EXPECT_EQ( numElements, adapter.getObject().size() );

View File

@ -24,11 +24,13 @@ TEST_F(TestPicoJsonAdapter, BasicArrayIteration)
// Ensure that wrapping the document preserves the array and does not allow
// it to be cast to other types
valijson::adapters::PicoJsonAdapter adapter(document);
#if VALIJSON_USE_EXCEPTIONS
ASSERT_NO_THROW( adapter.getArray() );
ASSERT_ANY_THROW( adapter.getBool() );
ASSERT_ANY_THROW( adapter.getDouble() );
ASSERT_ANY_THROW( adapter.getObject() );
ASSERT_ANY_THROW( adapter.getString() );
#endif
// Ensure that the array contains the expected number of elements
EXPECT_EQ( numElements, adapter.getArray().size() );
@ -61,11 +63,13 @@ TEST_F(TestPicoJsonAdapter, BasicObjectIteration)
// Ensure that wrapping the document preserves the object and does not
// allow it to be cast to other types
valijson::adapters::PicoJsonAdapter adapter(document);
#if VALIJSON_USE_EXCEPTIONS
ASSERT_NO_THROW( adapter.getObject() );
ASSERT_ANY_THROW( adapter.getArray() );
ASSERT_ANY_THROW( adapter.getBool() );
ASSERT_ANY_THROW( adapter.getDouble() );
ASSERT_ANY_THROW( adapter.getString() );
#endif
// Ensure that the object contains the expected number of members
EXPECT_EQ( numElements, adapter.getObject().size() );

View File

@ -23,11 +23,13 @@ TEST_F(TestPropertyTreeAdapter, BasicArrayIteration)
// Ensure that wrapping the document preserves the array and does not allow
// it to be cast to other types
valijson::adapters::PropertyTreeAdapter adapter(document);
#if VALIJSON_USE_EXCEPTIONS
ASSERT_NO_THROW( adapter.getArray() );
ASSERT_ANY_THROW( adapter.getBool() );
ASSERT_ANY_THROW( adapter.getDouble() );
ASSERT_ANY_THROW( adapter.getObject() );
ASSERT_ANY_THROW( adapter.getString() );
#endif
// Ensure that the array contains the expected number of elements
EXPECT_EQ( numElements, adapter.getArray().size() );
@ -62,11 +64,13 @@ TEST_F(TestPropertyTreeAdapter, BasicObjectIteration)
// Ensure that wrapping the document preserves the object and does not
// allow it to be cast to other types
valijson::adapters::PropertyTreeAdapter adapter(document);
#if VALIJSON_USE_EXCEPTIONS
ASSERT_NO_THROW( adapter.getObject() );
ASSERT_ANY_THROW( adapter.getArray() );
ASSERT_ANY_THROW( adapter.getBool() );
ASSERT_ANY_THROW( adapter.getDouble() );
ASSERT_ANY_THROW( adapter.getString() );
#endif
// Ensure that the object contains the expected number of members
EXPECT_EQ( numElements, adapter.getObject().size() );

View File

@ -26,11 +26,13 @@ void testBasicArrayIteration()
// Ensure that wrapping the document preserves the array and does not allow
// it to be cast to other types
valijson::adapters::RapidJsonAdapter adapter(document);
#if VALIJSON_USE_EXCEPTIONS
ASSERT_NO_THROW( adapter.getArray() );
ASSERT_ANY_THROW( adapter.getBool() );
ASSERT_ANY_THROW( adapter.getDouble() );
ASSERT_ANY_THROW( adapter.getObject() );
ASSERT_ANY_THROW( adapter.getString() );
#endif
// Ensure that the array contains the expected number of elements
EXPECT_EQ( numElements, adapter.getArray().size() );
@ -66,11 +68,13 @@ void testBasicObjectIteration()
// Ensure that wrapping the document preserves the object and does not
// allow it to be cast to other types
valijson::adapters::RapidJsonAdapter adapter(document);
#if VALIJSON_USE_EXCEPTIONS
ASSERT_NO_THROW( adapter.getObject() );
ASSERT_ANY_THROW( adapter.getArray() );
ASSERT_ANY_THROW( adapter.getBool() );
ASSERT_ANY_THROW( adapter.getDouble() );
ASSERT_ANY_THROW( adapter.getString() );
#endif
// Ensure that the object contains the expected number of members
EXPECT_EQ( numElements, adapter.getObject().size() );

View File

@ -36,7 +36,11 @@ TEST_F(TestValidationErrors, AllOfConstraintFailure)
// Parse schema document
Schema schema;
SchemaParser schemaParser;
ASSERT_NO_THROW( schemaParser.populateSchema(schemaAdapter, schema) );
#if VALIJSON_USE_EXCEPTIONS
ASSERT_NO_THROW(schemaParser.populateSchema(schemaAdapter, schema));
#else
schemaParser.populateSchema(schemaAdapter, schema);
#endif
// Load test document
rapidjson::Document testDocument;

View File

@ -16,6 +16,7 @@
#include <valijson/schema_parser.hpp>
#include <valijson/validation_results.hpp>
#include <valijson/validator.hpp>
#include <valijson/exceptions.hpp>
#ifdef VALIJSON_BUILD_POCO_ADAPTER
#include <valijson/adapters/poco_json_adapter.hpp>
@ -52,7 +53,7 @@ std::string getRelativePath(const std::string &uri)
return "../doc/schema/draft-04.json";
}
throw std::runtime_error("Attempt fetchDoc of " + uri);
valijson::throwRuntimeError("Attempt fetchDoc of " + uri);
}
template<typename AdapterType>
@ -66,7 +67,7 @@ const typename AdapterTraits<AdapterType>::DocumentType * fetchDocument(
if (!valijson::utils::loadDocument(relativePath, *document)) {
delete document;
throw std::runtime_error("Failed fetchDoc of " + uri);
valijson::throwRuntimeError("Failed fetchDoc of " + uri);
}
return document;
@ -89,8 +90,9 @@ protected:
std::string currentTestCase;
std::string currentTest;
#if VALIJSON_USE_EXCEPTIONS
try {
#endif
// Load test document
typename AdapterTraits<AdapterType>::DocumentType document;
ASSERT_TRUE( valijson::utils::loadDocument(testFile, document) );
@ -152,13 +154,14 @@ protected:
<< AdapterTraits<AdapterType>::adapterName() << "'";
}
}
#if VALIJSON_USE_EXCEPTIONS
} catch (const std::exception &e) {
FAIL() << "Exception thrown with message '" << e.what()
<< "' in '" << currentTest << "' of test case '"
<< currentTestCase << "' with adapter '"
<< AdapterTraits<AdapterType>::adapterName() << "'";
}
#endif
}
void processTestFile(const std::string &testFile,