mirror of
https://github.com/stedolan/jq.git
synced 2024-05-11 05:55:39 +00:00
Print offending object in runtime error messages
When reporting an error to the user, add information about the offending
object/value (possibly truncated).
The goal is to give a user some context regarding which input object
caused the runtime error.
Examples:
$ echo '"hello"' | ./jq '-.'
jq: error: string ("hello") cannot be negated
$ echo '"very-long-string"' | ./jq '-.'
jq: error: string ("very-long-...) cannot be negated
$ echo '["1",2]' | ./jq '.|join(",")'
jq: error: string (",") and number (2) cannot be added
$ echo '["1","2",{"a":{"b":{"c":33}}}]' | ./jq '.|join(",")'
jq: error: string (",") and object ({"a":{"b":{...) cannot be added
$ echo '{"a":{"b":{"c":33}}}' | ./jq '.a | @tsv'
jq: error: object ({"b":{"c":33}}) cannot be tsv-formatted, only array
(Fix #754)
This commit is contained in:
committed by
Nicolas Williams
parent
a50e548cc5
commit
7b6a018dff
@@ -22,17 +22,22 @@
|
||||
|
||||
|
||||
static jv type_error(jv bad, const char* msg) {
|
||||
jv err = jv_invalid_with_msg(jv_string_fmt("%s %s",
|
||||
char errbuf[15];
|
||||
jv err = jv_invalid_with_msg(jv_string_fmt("%s (%s) %s",
|
||||
jv_kind_name(jv_get_kind(bad)),
|
||||
jv_dump_string_trunc(jv_copy(bad), errbuf, sizeof(errbuf)),
|
||||
msg));
|
||||
jv_free(bad);
|
||||
return err;
|
||||
}
|
||||
|
||||
static jv type_error2(jv bad1, jv bad2, const char* msg) {
|
||||
jv err = jv_invalid_with_msg(jv_string_fmt("%s and %s %s",
|
||||
char errbuf1[15],errbuf2[15];
|
||||
jv err = jv_invalid_with_msg(jv_string_fmt("%s (%s) and %s (%s) %s",
|
||||
jv_kind_name(jv_get_kind(bad1)),
|
||||
jv_dump_string_trunc(jv_copy(bad1), errbuf1, sizeof(errbuf1)),
|
||||
jv_kind_name(jv_get_kind(bad2)),
|
||||
jv_dump_string_trunc(jv_copy(bad2), errbuf2, sizeof(errbuf2)),
|
||||
msg));
|
||||
jv_free(bad1);
|
||||
jv_free(bad2);
|
||||
|
||||
12
execute.c
12
execute.c
@@ -423,8 +423,10 @@ jv jq_next(jq_state *jq) {
|
||||
stack_push(jq, jv_object_set(objv, k, v));
|
||||
stack_push(jq, stktop);
|
||||
} else {
|
||||
set_error(jq, jv_invalid_with_msg(jv_string_fmt("Cannot use %s as object key",
|
||||
jv_kind_name(jv_get_kind(k)))));
|
||||
char errbuf[15];
|
||||
set_error(jq, jv_invalid_with_msg(jv_string_fmt("Cannot use %s (%s) as object key",
|
||||
jv_kind_name(jv_get_kind(k)),
|
||||
jv_dump_string_trunc(jv_copy(k), errbuf, sizeof(errbuf)))));
|
||||
jv_free(stktop);
|
||||
jv_free(v);
|
||||
jv_free(k);
|
||||
@@ -634,9 +636,11 @@ jv jq_next(jq_state *jq) {
|
||||
} else {
|
||||
assert(opcode == EACH || opcode == EACH_OPT);
|
||||
if (opcode == EACH) {
|
||||
char errbuf[15];
|
||||
set_error(jq,
|
||||
jv_invalid_with_msg(jv_string_fmt("Cannot iterate over %s",
|
||||
jv_kind_name(jv_get_kind(container)))));
|
||||
jv_invalid_with_msg(jv_string_fmt("Cannot iterate over %s (%s)",
|
||||
jv_kind_name(jv_get_kind(container)),
|
||||
jv_dump_string_trunc(jv_copy(container), errbuf, sizeof(errbuf)))));
|
||||
}
|
||||
keep_going = 0;
|
||||
}
|
||||
|
||||
1
jv.h
1
jv.h
@@ -171,6 +171,7 @@ void jv_dumpf(jv, FILE *f, int flags);
|
||||
void jv_dump(jv, int flags);
|
||||
void jv_show(jv, int flags);
|
||||
jv jv_dump_string(jv, int flags);
|
||||
char *jv_dump_string_trunc(jv x, char *outbuf, size_t bufsize);
|
||||
|
||||
enum {
|
||||
JV_PARSE_SEQ = 1,
|
||||
|
||||
16
jv_print.c
16
jv_print.c
@@ -313,3 +313,19 @@ jv jv_dump_string(jv x, int flags) {
|
||||
jvp_dtoa_context_free(&C);
|
||||
return s;
|
||||
}
|
||||
|
||||
char *jv_dump_string_trunc(jv x, char *outbuf, size_t bufsize) {
|
||||
x = jv_dump_string(x,0);
|
||||
const char* p = jv_string_value(x);
|
||||
const size_t len = strlen(p);
|
||||
strncpy(outbuf, p, bufsize);
|
||||
outbuf[bufsize - 1] = 0;
|
||||
if (len > bufsize - 1 && bufsize >= 4) {
|
||||
// Indicate truncation with '...'
|
||||
outbuf[bufsize - 2]='.';
|
||||
outbuf[bufsize - 3]='.';
|
||||
outbuf[bufsize - 4]='.';
|
||||
}
|
||||
jv_free(x);
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
@@ -1173,3 +1173,15 @@ import "test_bind_order" as check; check::check
|
||||
null
|
||||
true
|
||||
|
||||
try -. catch .
|
||||
"very-long-string"
|
||||
"string (\"very-long-...) cannot be negated"
|
||||
|
||||
try join(",") catch .
|
||||
["1",2]
|
||||
"string (\",\") and number (2) cannot be added"
|
||||
|
||||
try join(",") catch .
|
||||
["1","2",{"a":{"b":{"c":33}}}]
|
||||
"string (\",\") and object ({\"a\":{\"b\":{...) cannot be added"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user