json: return errors with more context, on failed json.decode() calls.
parent
829fed4af0
commit
f5e4d17cf3
|
@ -69,3 +69,49 @@ fn test_skip_fields_should_be_initialised_by_json_decode() ? {
|
||||||
assert task.total_comments == 55
|
assert task.total_comments == 55
|
||||||
assert task.comments == []
|
assert task.comments == []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
struct DbConfig {
|
||||||
|
host string
|
||||||
|
dbname string
|
||||||
|
user string
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_decode_error_message_should_have_enough_context_empty() {
|
||||||
|
json.decode(DbConfig, '') or {
|
||||||
|
assert err.msg().len < 2
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_decode_error_message_should_have_enough_context_just_brace() {
|
||||||
|
json.decode(DbConfig, '{') or {
|
||||||
|
assert err.msg() == '{'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_decode_error_message_should_have_enough_context_trailing_comma_at_end() {
|
||||||
|
txt := '{
|
||||||
|
"host": "localhost",
|
||||||
|
"dbname": "alex",
|
||||||
|
"user": "alex",
|
||||||
|
}'
|
||||||
|
json.decode(DbConfig, txt) or {
|
||||||
|
assert err.msg() == ' "user": "alex",\n}'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_decode_error_message_should_have_enough_context_in_the_middle() {
|
||||||
|
txt := '{"host": "localhost", "dbname": "alex" "user": "alex", "port": "1234"}'
|
||||||
|
json.decode(DbConfig, txt) or {
|
||||||
|
assert err.msg() == 'ost", "dbname": "alex" "user":'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert false
|
||||||
|
}
|
||||||
|
|
|
@ -73,9 +73,28 @@ $dec_fn_dec {
|
||||||
if (!root) {
|
if (!root) {
|
||||||
const char *error_ptr = cJSON_GetErrorPtr();
|
const char *error_ptr = cJSON_GetErrorPtr();
|
||||||
if (error_ptr != NULL) {
|
if (error_ptr != NULL) {
|
||||||
// fprintf(stderr, "Error in decode() for $styp error_ptr=: %s\\n", error_ptr);
|
char *prevline_ptr = (char*)error_ptr;
|
||||||
// printf("\\nbad js=%%s\\n", js.str);
|
int maxcontext_chars = 30;
|
||||||
return (Option_$styp){.state = 2,.err = _v_error(tos2((byteptr)error_ptr)),.data = {0}};
|
int backlines = 1;
|
||||||
|
int backchars = maxcontext_chars-7;
|
||||||
|
while(backchars--){
|
||||||
|
char prevc = *(prevline_ptr - 1);
|
||||||
|
if(0==prevc){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(10==prevc && !backlines--){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prevline_ptr--;
|
||||||
|
if(123==prevc) {
|
||||||
|
break; // stop at `{` too
|
||||||
|
}
|
||||||
|
}
|
||||||
|
byte *buf = _v_malloc(maxcontext_chars + 10);
|
||||||
|
vmemset(buf, 0, maxcontext_chars+10);
|
||||||
|
vmemcpy(buf, prevline_ptr, maxcontext_chars);
|
||||||
|
// for(int x=-10;x<10;x++){ char *xx = prevline_ptr+x; fprintf(stderr, "2 prevline_ptr + %d: %p | %c | %d \\n", x, xx, (int)(*(xx)), (int)(*(xx))); } fprintf(stderr, "--------\\n");
|
||||||
|
return (Option_$styp){.state = 2,.err = _v_error(tos2(buf)),.data = {0}};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
')
|
')
|
||||||
|
|
Loading…
Reference in New Issue