Compare commits

...
Author SHA1 Message Date
Niels Lohmann 379756e92e json_view: no byte range in exceptions about a removed value
#5990 dropped the found flag from diagnostics(), reasoning that a value
value_path() does not find leaves no tokens, like the root. But the node
of a value that is no longer part of the document still holds the bytes
it had in the source, so with JSON_DIAGNOSTICS and
JSON_DIAGNOSTIC_POSITIONS its exceptions gained "(bytes 1-4)" for text
that is no longer there. The test #5997 added for exactly this case
(unit-json_view_positions.cpp, "views of values that are no longer part
of the document") has failed on develop since both were merged.

Restore the flag: a value that is not found gets no context, the root
keeps its byte range.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-02 19:08:09 +01:00
Niels Lohmann b18b6fc7e6 Build the parser's syntax error prefix with one concat() (#6013)
Since #6004 made the "while parsing" part unconditional, the three appends
at the start of exception_message() are one fixed string around the
context. Review follow-up to #6004.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-02 18:27:08 +01:00
4 changed files with 22 additions and 16 deletions

No files matched your search

+1 -5
View File
@@ -573,11 +573,7 @@ class parser
std::string exception_message(const token_type expected, const std::string& context)
{
std::string error_msg = "syntax error ";
error_msg += concat("while parsing ", context, ' ');
error_msg += "- ";
std::string error_msg = concat("syntax error while parsing ", context, " - ");
if (last_token == token_type::parse_error)
{
+10 -3
View File
@@ -230,7 +230,8 @@ void value_range(const document_data& d, const node* n, std::size_t& start, std:
/// the context basic_json puts in front of the message of an exception about
/// a value: "(/path) " with JSON_DIAGNOSTICS (none for the root), then
/// "(bytes a-b) " with JSON_DIAGNOSTIC_POSITIONS (also for the root)
/// "(bytes a-b) " with JSON_DIAGNOSTIC_POSITIONS (also for the root); with
/// JSON_DIAGNOSTICS, nothing for a value that is no longer part of the document
///
/// This and the throw helpers that take an error_site are templates, so that
/// the path and range code is instantiated only where an exception can be
@@ -251,8 +252,14 @@ std::string diagnostics(const error_site site)
std::string context;
#if JSON_DIAGNOSTICS
std::vector<std::string> tokens;
// a value that is not found leaves no tokens, like the root
static_cast<void>(edited ? value_path<true>(d, site.value(), tokens) : value_path<false>(d, site.value(), tokens));
// a value that is no longer part of the document has no path, and its
// node still holds the bytes it had in the source: no context at all
const bool found = edited ? value_path<true>(d, site.value(), tokens) : value_path<false>(d, site.value(), tokens);
if (!found)
{
// context is still empty; returning it keeps the copy elided (-Wnrvo)
return context;
}
if (!tokens.empty())
{
// the root value has no path, but still has a byte range
+1 -5
View File
@@ -23802,11 +23802,7 @@ class parser
std::string exception_message(const token_type expected, const std::string& context)
{
std::string error_msg = "syntax error ";
error_msg += concat("while parsing ", context, ' ');
error_msg += "- ";
std::string error_msg = concat("syntax error while parsing ", context, " - ");
if (last_token == token_type::parse_error)
{
+10 -3
View File
@@ -5059,7 +5059,8 @@ void value_range(const document_data& d, const node* n, std::size_t& start, std:
/// the context basic_json puts in front of the message of an exception about
/// a value: "(/path) " with JSON_DIAGNOSTICS (none for the root), then
/// "(bytes a-b) " with JSON_DIAGNOSTIC_POSITIONS (also for the root)
/// "(bytes a-b) " with JSON_DIAGNOSTIC_POSITIONS (also for the root); with
/// JSON_DIAGNOSTICS, nothing for a value that is no longer part of the document
///
/// This and the throw helpers that take an error_site are templates, so that
/// the path and range code is instantiated only where an exception can be
@@ -5080,8 +5081,14 @@ std::string diagnostics(const error_site site)
std::string context;
#if JSON_DIAGNOSTICS
std::vector<std::string> tokens;
// a value that is not found leaves no tokens, like the root
static_cast<void>(edited ? value_path<true>(d, site.value(), tokens) : value_path<false>(d, site.value(), tokens));
// a value that is no longer part of the document has no path, and its
// node still holds the bytes it had in the source: no context at all
const bool found = edited ? value_path<true>(d, site.value(), tokens) : value_path<false>(d, site.value(), tokens);
if (!found)
{
// context is still empty; returning it keeps the copy elided (-Wnrvo)
return context;
}
if (!tokens.empty())
{
// the root value has no path, but still has a byte range