From a4eeeb079809071bfc93f8fdf43a2ebe481df3a8 Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Mon, 27 Jan 2025 15:18:54 -0500 Subject: [PATCH] Improve error reporting -JSON syntax errors say they are syntax errors, to help people understand how to resolve them. -The line and character offset of JSON errors has been made explicit, instead of requiring you to guess what the numbers mean. -The C++ source file names/etc were made more explicit as well, which should hopefully reduce people asking "I can't find this .cpp file on my game, where is it" --- src/debug.cpp | 10 +++++----- src/flexbuffer_json.cpp | 28 ++++++++++++++-------------- src/generic_factory.h | 12 ++++++++---- src/json.cpp | 4 ++-- 4 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/debug.cpp b/src/debug.cpp index fc1d9d53879dd..4b51f87ff1560 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -317,11 +317,11 @@ static void debug_error_prompt( std::string formatted_report = string_format( // developer-facing error report. INTENTIONALLY UNTRANSLATED! - " DEBUG : %s\n\n" - " FUNCTION : %s\n" - " FILE : %s\n" - " LINE : %s\n" - " VERSION : %s\n", + " DEBUG : %s\n\n" + " REPORTING FUNCTION : %s\n" + " C++ SOURCE FILE : %s\n" + " LINE : %s\n" + " VERSION : %s\n", text, funcname, filename, line, getVersionString() ); diff --git a/src/flexbuffer_json.cpp b/src/flexbuffer_json.cpp index 28c279d04c7f1..d93ea34b1ceb4 100644 --- a/src/flexbuffer_json.cpp +++ b/src/flexbuffer_json.cpp @@ -143,7 +143,7 @@ std::string Json::str() const bool JsonValue::read( bool &b, bool throw_on_error ) const { if( !test_bool() ) { - return error_or_false( throw_on_error, "Expected bool" ); + return error_or_false( throw_on_error, "Syntax error. Expected bool" ); } b = get_bool(); return true; @@ -151,7 +151,7 @@ bool JsonValue::read( bool &b, bool throw_on_error ) const bool JsonValue::read( char &c, bool throw_on_error ) const { if( !test_number() ) { - return error_or_false( throw_on_error, "Expected number" ); + return error_or_false( throw_on_error, "Syntax error. Expected number" ); } c = get_int(); return true; @@ -159,7 +159,7 @@ bool JsonValue::read( char &c, bool throw_on_error ) const bool JsonValue::read( signed char &c, bool throw_on_error ) const { if( !test_number() ) { - return error_or_false( throw_on_error, "Expected number" ); + return error_or_false( throw_on_error, "Syntax error. Expected number" ); } // TODO: test for overflow c = get_int(); @@ -168,7 +168,7 @@ bool JsonValue::read( signed char &c, bool throw_on_error ) const bool JsonValue::read( unsigned char &c, bool throw_on_error ) const { if( !test_number() ) { - return error_or_false( throw_on_error, "Expected number" ); + return error_or_false( throw_on_error, "Syntax error. Expected number" ); } // TODO: test for overflow c = get_int(); @@ -177,7 +177,7 @@ bool JsonValue::read( unsigned char &c, bool throw_on_error ) const bool JsonValue::read( short unsigned int &s, bool throw_on_error ) const { if( !test_number() ) { - return error_or_false( throw_on_error, "Expected number" ); + return error_or_false( throw_on_error, "Syntax error. Expected number" ); } // TODO: test for overflow s = get_int(); @@ -186,7 +186,7 @@ bool JsonValue::read( short unsigned int &s, bool throw_on_error ) const bool JsonValue::read( short int &s, bool throw_on_error ) const { if( !test_number() ) { - return error_or_false( throw_on_error, "Expected number" ); + return error_or_false( throw_on_error, "Syntax error. Expected number" ); } // TODO: test for overflow s = get_int(); @@ -195,7 +195,7 @@ bool JsonValue::read( short int &s, bool throw_on_error ) const bool JsonValue::read( int &i, bool throw_on_error ) const { if( !test_number() ) { - return error_or_false( throw_on_error, "Expected number" ); + return error_or_false( throw_on_error, "Syntax error. Expected number" ); } i = get_int(); return true; @@ -203,7 +203,7 @@ bool JsonValue::read( int &i, bool throw_on_error ) const bool JsonValue::read( int64_t &i, bool throw_on_error ) const { if( !test_number() ) { - return error_or_false( throw_on_error, "Expected number" ); + return error_or_false( throw_on_error, "Syntax error. Expected number" ); } i = get_int64(); return true; @@ -211,7 +211,7 @@ bool JsonValue::read( int64_t &i, bool throw_on_error ) const bool JsonValue::read( uint64_t &i, bool throw_on_error ) const { if( !test_number() ) { - return error_or_false( throw_on_error, "Expected number" ); + return error_or_false( throw_on_error, "Syntax error. Expected number" ); } i = get_uint64(); return true; @@ -219,7 +219,7 @@ bool JsonValue::read( uint64_t &i, bool throw_on_error ) const bool JsonValue::read( unsigned int &u, bool throw_on_error ) const { if( !test_number() ) { - return error_or_false( throw_on_error, "Expected number" ); + return error_or_false( throw_on_error, "Syntax error. Expected number" ); } u = get_uint(); return true; @@ -227,7 +227,7 @@ bool JsonValue::read( unsigned int &u, bool throw_on_error ) const bool JsonValue::read( float &f, bool throw_on_error ) const { if( !test_number() ) { - return error_or_false( throw_on_error, "Expected number" ); + return error_or_false( throw_on_error, "Syntax error. Expected number" ); } f = get_float(); return true; @@ -235,7 +235,7 @@ bool JsonValue::read( float &f, bool throw_on_error ) const bool JsonValue::read( double &d, bool throw_on_error ) const { if( !test_number() ) { - return error_or_false( throw_on_error, "Expected number" ); + return error_or_false( throw_on_error, "Syntax error. Expected number" ); } d = get_float(); return true; @@ -243,7 +243,7 @@ bool JsonValue::read( double &d, bool throw_on_error ) const bool JsonValue::read( std::string &s, bool throw_on_error ) const { if( !test_string() ) { - return error_or_false( throw_on_error, "Expected string" ); + return error_or_false( throw_on_error, "Syntax error. Expected string" ); } s = get_string(); return true; @@ -340,7 +340,7 @@ void JsonObject::error_skipped_members( const std::vector &skipped_membe "\"//~\" should be within a text object and contain comments for translators." ); } else { jo.throw_error_at( name.c_str(), - string_format( "Invalid or misplaced field name \"%s\" in JSON data", + string_format( "Unread data. Invalid or misplaced field name \"%s\" in JSON data", name.c_str() ) ); } } catch( const JsonError &e ) { diff --git a/src/generic_factory.h b/src/generic_factory.h index 1a663f5e66f91..a64142733612e 100644 --- a/src/generic_factory.h +++ b/src/generic_factory.h @@ -565,9 +565,11 @@ inline void mandatory( const JsonObject &jo, const bool was_loaded, const std::s if( !jo.read( name, member ) ) { if( !was_loaded ) { if( jo.has_member( name ) ) { - jo.throw_error( str_cat( "failed to read mandatory member \"", name, "\"" ) ); + jo.throw_error( str_cat( "object beginning at this line failed to read mandatory member \"", name, + "\"" ) ); } else { - jo.throw_error( str_cat( "missing mandatory member \"", name, "\"" ) ); + jo.throw_error( str_cat( "object beginning at this line missing mandatory member \"", name, + "\"" ) ); } } } @@ -579,9 +581,11 @@ inline void mandatory( const JsonObject &jo, const bool was_loaded, const std::s if( !reader( jo, name, member, was_loaded ) ) { if( !was_loaded ) { if( jo.has_member( name ) ) { - jo.throw_error( str_cat( "failed to read mandatory member \"", name, "\"" ) ); + jo.throw_error( str_cat( "object beginning at this line failed to read mandatory member \"", name, + "\"" ) ); } else { - jo.throw_error( str_cat( "missing mandatory member \"", name, "\"" ) ); + jo.throw_error( str_cat( "object beginning at this line missing mandatory member \"", name, + "\"" ) ); } } } diff --git a/src/json.cpp b/src/json.cpp index 9b0d48d1a30c1..aecdebea27e75 100644 --- a/src/json.cpp +++ b/src/json.cpp @@ -1889,7 +1889,7 @@ std::string TextJsonIn::line_number( int offset_modifier ) std::stringstream ret; switch( error_log_format ) { case error_log_format_t::human_readable: - ret << name << ":" << line << ":" << offset; + ret << "file " << name << ", at line " << line << ", character " << offset; break; case error_log_format_t::github_action: ret.imbue( std::locale::classic() ); @@ -2012,7 +2012,7 @@ void TextJsonIn::error( int offset, const std::string &message ) std::ostringstream err_header; switch( error_log_format ) { case error_log_format_t::human_readable: - err_header << "Json error: " << line_number( offset ) << ": "; + err_header << "Json error: " << line_number( offset ) << ":\n"; break; case error_log_format_t::github_action: err_header << "::error " << line_number( offset ) << "::";