Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Namespace JSON-related errors #1499

Merged
merged 1 commit into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/core/json/include/sourcemeta/core/json.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ namespace sourcemeta::core {
/// assert(document.is_array());
/// ```
///
/// If parsing fails, sourcemeta::core::ParseError will be thrown.
/// If parsing fails, sourcemeta::core::JSONParseError will be thrown.
SOURCEMETA_CORE_JSON_EXPORT
auto parse_json(std::basic_istream<JSON::Char, JSON::CharTraits> &stream,
const JSON::ParseCallback &callback = nullptr) -> JSON;
Expand All @@ -63,7 +63,7 @@ auto parse_json(std::basic_istream<JSON::Char, JSON::CharTraits> &stream,
/// assert(document.is_array());
/// ```
///
/// If parsing fails, sourcemeta::core::ParseError will be thrown.
/// If parsing fails, sourcemeta::core::JSONParseError will be thrown.
SOURCEMETA_CORE_JSON_EXPORT
auto parse_json(const std::basic_string<JSON::Char, JSON::CharTraits> &input,
const JSON::ParseCallback &callback = nullptr) -> JSON;
Expand Down Expand Up @@ -125,7 +125,7 @@ auto parse_json(const std::basic_string<JSON::Char, JSON::CharTraits> &input,
/// std::cout << std::endl;
/// ```
///
/// If parsing fails, sourcemeta::core::ParseError will be thrown.
/// If parsing fails, sourcemeta::core::JSONParseError will be thrown.
SOURCEMETA_CORE_JSON_EXPORT
auto read_json(const std::filesystem::path &path) -> JSON;

Expand All @@ -147,7 +147,7 @@ auto read_json(const std::filesystem::path &path) -> JSON;
/// std::cout << std::endl;
/// ```
///
/// If parsing fails, sourcemeta::core::ParseError will be thrown.
/// If parsing fails, sourcemeta::core::JSONParseError will be thrown.
SOURCEMETA_CORE_JSON_EXPORT
auto read_file(const std::filesystem::path &path)
-> std::basic_ifstream<JSON::Char, JSON::CharTraits>;
Expand Down
17 changes: 9 additions & 8 deletions src/core/json/include/sourcemeta/core/json_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ namespace sourcemeta::core {

/// @ingroup json
/// This class represents a parsing error
class SOURCEMETA_CORE_JSON_EXPORT ParseError : public std::exception {
class SOURCEMETA_CORE_JSON_EXPORT JSONParseError : public std::exception {
public:
/// Create a parsing error
ParseError(const std::uint64_t line, const std::uint64_t column)
JSONParseError(const std::uint64_t line, const std::uint64_t column)
: line_{line}, column_{column} {}

[[nodiscard]] auto what() const noexcept -> const char * override {
Expand All @@ -45,16 +45,17 @@ class SOURCEMETA_CORE_JSON_EXPORT ParseError : public std::exception {

/// @ingroup json
/// This class represents a parsing error occurring from parsing a file
class SOURCEMETA_CORE_JSON_EXPORT FileParseError : public ParseError {
class SOURCEMETA_CORE_JSON_EXPORT JSONFileParseError : public JSONParseError {
public:
/// Create a file parsing error
FileParseError(const std::filesystem::path &path, const std::uint64_t line,
const std::uint64_t column)
: ParseError{line, column}, path_{path} {}
JSONFileParseError(const std::filesystem::path &path,
const std::uint64_t line, const std::uint64_t column)
: JSONParseError{line, column}, path_{path} {}

/// Create a file parsing error from a parse error
FileParseError(const std::filesystem::path &path, const ParseError &parent)
: ParseError{parent.line(), parent.column()}, path_{path} {}
JSONFileParseError(const std::filesystem::path &path,
const JSONParseError &parent)
: JSONParseError{parent.line(), parent.column()}, path_{path} {}

/// Get the fiel path of the error
[[nodiscard]] auto path() const noexcept -> const std::filesystem::path {
Expand Down
4 changes: 2 additions & 2 deletions src/core/json/json.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ auto read_json(const std::filesystem::path &path) -> JSON {
auto stream{read_file(path)};
try {
return parse_json(stream);
} catch (const ParseError &error) {
} catch (const JSONParseError &error) {
// For producing better error messages
throw FileParseError(path, error);
throw JSONFileParseError(path, error);
}
}

Expand Down
46 changes: 23 additions & 23 deletions src/core/json/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ inline auto parse_null(
1)) {
column += 1;
if (stream.get() != character) {
throw ParseError(line, column);
throw JSONParseError(line, column);
}
}

Expand All @@ -45,7 +45,7 @@ inline auto parse_boolean_true(
1)) {
column += 1;
if (stream.get() != character) {
throw ParseError(line, column);
throw JSONParseError(line, column);
}
}

Expand All @@ -62,7 +62,7 @@ inline auto parse_boolean_false(
1)) {
column += 1;
if (stream.get() != character) {
throw ParseError(line, column);
throw JSONParseError(line, column);
}
}

Expand Down Expand Up @@ -97,7 +97,7 @@ auto parse_string_unicode_code_point(
if (std::isxdigit(code_point[code_point_size])) {
code_point_size += 1;
} else {
throw ParseError(line, column);
throw JSONParseError(line, column);
}
}

Expand Down Expand Up @@ -127,13 +127,13 @@ auto parse_string_unicode(
// Next, we expect "\"
column += 1;
if (stream.get() != internal::token_string_escape<CharT>) {
throw ParseError(line, column);
throw JSONParseError(line, column);
}

// Next, we expect "u"
column += 1;
if (stream.get() != internal::token_string_escape_unicode<CharT>) {
throw ParseError(line, column);
throw JSONParseError(line, column);
}

// Finally, get the low code point of the surrogate and calculate
Expand All @@ -147,7 +147,7 @@ auto parse_string_unicode(
code_point =
0x10000 + ((code_point - 0xD800) << 10) + (low_code_point - 0xDC00);
} else {
throw ParseError(line, column);
throw JSONParseError(line, column);
}
}

Expand Down Expand Up @@ -218,7 +218,7 @@ auto parse_string_escape(
return;

default:
throw ParseError(line, column);
throw JSONParseError(line, column);
}
}

Expand Down Expand Up @@ -276,14 +276,14 @@ auto parse_string(
case '\u001E':
case '\u001F':
case static_cast<typename JSON::Char>(JSON::CharTraits::eof()):
throw ParseError(line, column);
throw JSONParseError(line, column);
default:
result.put(character);
break;
}
}

throw ParseError(line, column);
throw JSONParseError(line, column);
}

template <typename CharT, typename Traits>
Expand All @@ -293,7 +293,7 @@ auto parse_number_integer(const std::uint64_t line, const std::uint64_t column,
try {
return std::stoll(string);
} catch (const std::out_of_range &) {
throw ParseError(line, column);
throw JSONParseError(line, column);
}
}

Expand All @@ -304,7 +304,7 @@ auto parse_number_real(const std::uint64_t line, const std::uint64_t column,
try {
return std::stod(string);
} catch (const std::out_of_range &) {
throw ParseError(line, column);
throw JSONParseError(line, column);
}
}

Expand Down Expand Up @@ -338,7 +338,7 @@ auto parse_number_exponent_rest(
}
}

throw ParseError(line, column);
throw JSONParseError(line, column);
}

auto parse_number_exponent(
Expand Down Expand Up @@ -366,7 +366,7 @@ auto parse_number_exponent(
return parse_number_exponent_rest(line, column, original_column, stream,
result);
default:
throw ParseError(line, column);
throw JSONParseError(line, column);
}
}

Expand Down Expand Up @@ -405,7 +405,7 @@ auto parse_number_exponent_first(
return parse_number_exponent_rest(line, column, original_column, stream,
result);
default:
throw ParseError(line, column);
throw JSONParseError(line, column);
}
}

Expand Down Expand Up @@ -450,7 +450,7 @@ auto parse_number_fractional(
}
}

throw ParseError(line, column);
throw JSONParseError(line, column);
}

auto parse_number_fractional_first(
Expand All @@ -469,7 +469,7 @@ auto parse_number_fractional_first(
case internal::token_number_decimal_point<typename JSON::Char>:
case static_cast<typename JSON::Char>(JSON::CharTraits::eof()):
column += 1;
throw ParseError(line, column);
throw JSONParseError(line, column);
case internal::token_number_zero<typename JSON::Char>:
case internal::token_number_one<typename JSON::Char>:
case internal::token_number_two<typename JSON::Char>:
Expand Down Expand Up @@ -526,7 +526,7 @@ auto parse_number_maybe_fractional(
case internal::token_number_eight<typename JSON::Char>:
case internal::token_number_nine<typename JSON::Char>:
column += 1;
throw ParseError(line, column);
throw JSONParseError(line, column);
default:
return JSON{parse_number_integer(line, original_column, result.str())};
}
Expand Down Expand Up @@ -578,7 +578,7 @@ auto parse_number_any_rest(
}
}

throw ParseError(line, column);
throw JSONParseError(line, column);
}

auto parse_number_any_negative_first(
Expand Down Expand Up @@ -612,7 +612,7 @@ auto parse_number_any_negative_first(
return parse_number_any_rest(line, column, original_column, stream,
result);
default:
throw ParseError(line, column);
throw JSONParseError(line, column);
}
}

Expand Down Expand Up @@ -783,7 +783,7 @@ auto internal_parse_json(
case internal::token_whitespace_space<typename JSON::Char>:
goto do_parse;
default:
throw ParseError(line, column);
throw JSONParseError(line, column);
}

/*
Expand Down Expand Up @@ -828,7 +828,7 @@ auto internal_parse_json(
CALLBACK_POST(Array, frames.top().get());
goto do_parse_container_end;
} else {
throw ParseError(line, column);
throw JSONParseError(line, column);
}

// Values
Expand Down Expand Up @@ -1172,7 +1172,7 @@ auto internal_parse_json(
frames.pop();
}

throw ParseError(line, column);
throw JSONParseError(line, column);

do_parse_container_end:
assert(!levels.empty());
Expand Down
2 changes: 1 addition & 1 deletion src/core/jsonl/include/sourcemeta/core/jsonl.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class SOURCEMETA_CORE_JSONL_EXPORT JSONL {
/// }
/// ```
///
/// If parsing fails, sourcemeta::core::ParseError will be thrown.
/// If parsing fails, sourcemeta::core::JSONParseError will be thrown.
JSONL(std::basic_istream<JSON::Char, JSON::CharTraits> &stream);

using const_iterator = ConstJSONLIterator;
Expand Down
2 changes: 1 addition & 1 deletion src/core/jsonl/iterator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ auto ConstJSONLIterator::operator++() -> ConstJSONLIterator & {
goto end;
default:
this->column += 1;
throw ParseError(this->line, this->column);
throw JSONParseError(this->line, this->column);
}

element:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ namespace sourcemeta::core {

/// @ingroup jsonpointer
/// This class represents a parsing error.
class SOURCEMETA_CORE_JSONPOINTER_EXPORT PointerParseError : public ParseError {
class SOURCEMETA_CORE_JSONPOINTER_EXPORT PointerParseError
// TODO: It makes no sense for a JSON Pointer error to inherit from a JSON
// error. Make them independent
: public JSONParseError {
public:
/// Create a parsing error
PointerParseError(const std::uint64_t column) : ParseError{1, column} {}
PointerParseError(const std::uint64_t column) : JSONParseError{1, column} {}

[[nodiscard]] auto what() const noexcept -> const char * override {
return "The input is not a valid JSON Pointer";
Expand Down
2 changes: 1 addition & 1 deletion src/core/yaml/yaml.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ static auto yaml_node_to_json(yaml_node_t *const node,
// Looks like it is very hard in YAML, given a scalar value, to
// determine whether it is a string or something else without attempting
// to parsing it and potentially failing to do so
} catch (const sourcemeta::core::ParseError &) {
} catch (const sourcemeta::core::JSONParseError &) {
return sourcemeta::core::JSON{input};
}
}
Expand Down
9 changes: 5 additions & 4 deletions test/json/json_error_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
#include <type_traits> // std::is_base_of_v

TEST(JSON_error, parse_error) {
static_assert(std::is_base_of_v<std::exception, sourcemeta::core::ParseError>,
"Must subclass std::exception");
auto exception{sourcemeta::core::ParseError(5, 6)};
EXPECT_THROW(throw exception, sourcemeta::core::ParseError);
static_assert(
std::is_base_of_v<std::exception, sourcemeta::core::JSONParseError>,
"Must subclass std::exception");
auto exception{sourcemeta::core::JSONParseError(5, 6)};
EXPECT_THROW(throw exception, sourcemeta::core::JSONParseError);
EXPECT_EQ(std::string{exception.what()}, "Failed to parse the JSON document");
EXPECT_EQ(exception.line(), 5);
EXPECT_EQ(exception.column(), 6);
Expand Down
4 changes: 2 additions & 2 deletions test/json/json_parse_error_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
try { \
sourcemeta::core::parse_json((input)); \
FAIL() << "The parse function was expected to throw"; \
} catch (const sourcemeta::core::ParseError &error) { \
} catch (const sourcemeta::core::JSONParseError &error) { \
EXPECT_EQ(error.line(), expected_line); \
EXPECT_EQ(error.column(), expected_column); \
SUCCEED(); \
Expand Down Expand Up @@ -633,7 +633,7 @@ TEST(JSON_parse_error, read_json_invalid) {
try {
sourcemeta::core::read_json(std::filesystem::path{TEST_DIRECTORY} /
"stub_invalid.json");
} catch (const sourcemeta::core::FileParseError &error) {
} catch (const sourcemeta::core::JSONFileParseError &error) {
EXPECT_EQ(error.path(),
std::filesystem::path{TEST_DIRECTORY} / "stub_invalid.json");
EXPECT_EQ(error.line(), 3);
Expand Down
2 changes: 1 addition & 1 deletion test/json/jsontestsuite.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class JSONTest : public testing::Test {
while (!stream.eof()) {
sourcemeta::core::parse_json(stream);
}
} catch (const sourcemeta::core::ParseError &) {
} catch (const sourcemeta::core::JSONParseError &) {
SUCCEED();
} catch (const std::exception &) {
FAIL() << "The parse function threw an unexpected error";
Expand Down
2 changes: 1 addition & 1 deletion test/jsonl/jsonl_parse_error_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
while (iterator != parser.cend()) \
++iterator; \
FAIL() << "The JSONL parser was expected to throw"; \
} catch (const sourcemeta::core::ParseError &error) { \
} catch (const sourcemeta::core::JSONParseError &error) { \
EXPECT_EQ(error.line(), expected_line); \
EXPECT_EQ(error.column(), expected_column); \
SUCCEED(); \
Expand Down
2 changes: 1 addition & 1 deletion test/jsonpointer/jsonpointer_parse_error_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
stream << "\"" << (input) << "\""; \
sourcemeta::core::parse_json(stream.str()); \
FAIL() << "The parse function was expected to throw"; \
} catch (const sourcemeta::core::ParseError &) { \
} catch (const sourcemeta::core::JSONParseError &) { \
SUCCEED(); \
} catch (const std::exception &) { \
FAIL() << "The parse operation threw an unexpected error"; \
Expand Down