From e792e42cfc8937da3d5ed1ce53f97c6f4ad2a8eb Mon Sep 17 00:00:00 2001 From: Cyrus Harrison Date: Sun, 16 Jul 2017 22:02:00 -0700 Subject: [PATCH] add line and char info to json parse error msgs --- src/libs/conduit/conduit_generator.cpp | 63 +++++++++++++++++++++----- src/tests/conduit/t_conduit_json.cpp | 48 ++++++++++++++++++++ 2 files changed, 99 insertions(+), 12 deletions(-) diff --git a/src/libs/conduit/conduit_generator.cpp b/src/libs/conduit/conduit_generator.cpp index e3a8535d0..2ea92028a 100644 --- a/src/libs/conduit/conduit_generator.cpp +++ b/src/libs/conduit/conduit_generator.cpp @@ -74,14 +74,15 @@ /// errors related to rapidjson parsing. // //----------------------------------------------------------------------------- -#define CONDUIT_JSON_PARSE_ERROR( document ) \ -{ \ - CONDUIT_ERROR("JSON parse error: \n" \ - << " offset: " << document.GetErrorOffset() \ - << "\n" \ - << " message:\n" \ - << GetParseError_En(document.GetParseError()) \ - << "\n"); \ +#define CONDUIT_JSON_PARSE_ERROR(json_str, document ) \ +{ \ + std::ostringstream __json_parse_oss; \ + Generator::Parser::parse_error_details( json_str, \ + document, \ + __json_parse_oss); \ + CONDUIT_ERROR("JSON parse error: \n" \ + << __json_parse_oss.str() \ + << "\n"); \ } //----------------------------------------------------------------------------- @@ -156,6 +157,10 @@ namespace conduit static void parse_base64(Node *node, const rapidjson::Value &jvalue); + static void parse_error_details(const std::string &json, + const rapidjson::Document &document, + std::ostream &os); + }; //---------------------------------------------------------------------------// @@ -1194,6 +1199,40 @@ Generator::Parser::parse_base64(Node *node, } } +//---------------------------------------------------------------------------// +void +Generator::Parser::parse_error_details(const std::string &json, + const rapidjson::Document &document, + std::ostream &os) +{ + // provide message with line + char from rapidjson parse error offset + index_t doc_offset = (index_t)document.GetErrorOffset(); + std::string json_curr = json.substr(0,doc_offset); + + std::string curr = ""; + std::string next = " "; + + index_t doc_line = 0; + index_t doc_char = 0; + + while(!next.empty()) + { + utils::split_string(json_curr, "\n", curr, next); + doc_char = curr.size(); + json_curr = next; + if(!next.empty()) + { + doc_line++; + } + } + + os << " parse error message:\n" + << GetParseError_En(document.GetParseError()) << "\n" + << " offset: " << doc_offset << "\n" + << " line: " << doc_line << "\n" + << " character: " << doc_char << "\n" + << " json:\n" << json << "\n"; +} //----------------------------------------------------------------------------- // -- end conduit::Generator::Parser -- @@ -1284,7 +1323,7 @@ Generator::walk(Schema &schema) const if(document.Parse(res.c_str()).HasParseError()) { - CONDUIT_JSON_PARSE_ERROR(document); + CONDUIT_JSON_PARSE_ERROR(res, document); } index_t curr_offset = 0; Parser::walk_json_schema(&schema,document,curr_offset); @@ -1313,7 +1352,7 @@ Generator::walk_external(Node &node) const if(document.Parse(res.c_str()).HasParseError()) { - CONDUIT_JSON_PARSE_ERROR(document); + CONDUIT_JSON_PARSE_ERROR(res, document); } Parser::walk_pure_json_schema(&node, @@ -1327,7 +1366,7 @@ Generator::walk_external(Node &node) const if(document.Parse(res.c_str()).HasParseError()) { - CONDUIT_JSON_PARSE_ERROR(document); + CONDUIT_JSON_PARSE_ERROR(res, document); } Parser::parse_base64(&node, document); @@ -1339,7 +1378,7 @@ Generator::walk_external(Node &node) const if(document.Parse(res.c_str()).HasParseError()) { - CONDUIT_JSON_PARSE_ERROR(document); + CONDUIT_JSON_PARSE_ERROR(res, document); } index_t curr_offset = 0; diff --git a/src/tests/conduit/t_conduit_json.cpp b/src/tests/conduit/t_conduit_json.cpp index 173da28fe..defc5f9d2 100644 --- a/src/tests/conduit/t_conduit_json.cpp +++ b/src/tests/conduit/t_conduit_json.cpp @@ -630,6 +630,54 @@ TEST(conduit_json, json_inf_and_nan) +//----------------------------------------------------------------------------- +TEST(conduit_json, json_parse_error_detailed) +{ + + try + { + std::string pure_json = "{\"value\": \n \n \n \n \"\\\"mystring!\\\"\" \n :}"; + Generator g(pure_json,"json"); + + Node n_res; + g.walk(n_res); + } + catch(conduit::Error e) + { + CONDUIT_INFO(e.message()); + } + + + try + { + std::string pure_json = "{\"value\":\"\\\"mystring!\\\"\" :}"; + Generator g(pure_json,"json"); + + Node n_res; + g.walk(n_res); + } + catch(conduit::Error e) + { + CONDUIT_INFO(e.message()); + } + + try + { + std::string pure_json = "\n\n\n\n\n\n{\"value\":\"\\\"mystring!\\\"\" :}"; + Generator g(pure_json,"json"); + + Node n_res; + g.walk(n_res); + } + catch(conduit::Error e) + { + CONDUIT_INFO(e.message()); + } + + +} + +