Keep the byte range in exceptions about the root value (#5990)

* Keep the byte range in exceptions about the root value (#5987)

With JSON_DIAGNOSTICS and JSON_DIAGNOSTIC_POSITIONS both set, exception::diagnostics()
and the json_view diagnostics() returned early for a value without a path (the
root), dropping "(bytes a-b)". Build the "(path) " prefix only when there are
tokens and always append the byte range.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Guard the null value of a value-initialized iterator; drop the unneeded found flag

With the root's byte range, diagnostics() reaches get_byte_positions() also
with JSON_DIAGNOSTICS when there is no value, as for a value-initialized
iterator (invalid_iterator.212). get_byte_positions() now returns no range
for a null value, the same change as #6003, so either can be merged first.

In the view, a value that value_path() does not find leaves no tokens, so the
found flag added nothing to the tokens.empty() test.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann authored and GitHub committed 2026-11-02 17:50:40 +01:00
1 parent 7328310136
commit ff0bdfdef3
7 files changed
+92 -50

No files matched your search

+22
View File
@@ -193,6 +193,28 @@ TEST_CASE("Better diagnostics with positions")
check_conversion(300);
}
SECTION("exception about the root value (#5987)")
{
// the root has no path, but still has a byte range
const json root = json::parse("true");
const json nested = json::parse("[1, true]");
const json constructed = true;
#if JSON_DIAGNOSTICS
CHECK_THROWS_WITH_AS(root.get<std::string>(),
"[json.exception.type_error.302] (bytes 0-4) type must be string, but is boolean", json::type_error);
CHECK_THROWS_WITH_AS(nested[1].get<std::string>(),
"[json.exception.type_error.302] (/1) (bytes 4-8) type must be string, but is boolean", json::type_error);
#else
CHECK_THROWS_WITH_AS(root.get<std::string>(),
"[json.exception.type_error.302] (bytes 0-4) type must be string, but is boolean", json::type_error);
CHECK_THROWS_WITH_AS(nested[1].get<std::string>(),
"[json.exception.type_error.302] (bytes 4-8) type must be string, but is boolean", json::type_error);
#endif
// a value without positions gets no range and no stray whitespace
CHECK_THROWS_WITH_AS(constructed.get<std::string>(),
"[json.exception.type_error.302] type must be string, but is boolean", json::type_error);
}
SECTION("JSON patch add to primitive parent (#4292)")
{
// the JSON Patch "add" target /foo/bar/baz has a string parent