Parse jsonnet files and list all errors - don't fail after first error

175 views
Skip to first unread message

Sandy Walsh

unread,
May 30, 2022, 3:54:12 PM5/30/22
to Jsonnet
Hi!

I've been creating some funky jsonnet lately and want to be able to use it to give hints to the user about missing fields and required data. 

But the cmdline seems to only want to report one error at a time. The asserts don't even get hit if the parsing doesn't pass. 

Is there a way to get a list of all parsing errors? Or is that something I have to do from the golang side of the fence? 

Thanks

Dave Cunningham

unread,
May 30, 2022, 4:22:33 PM5/30/22
to Sandy Walsh, Jsonnet
It is possible to write a parser such that if it cannot parse the stream of tokens, it skips over the offending tokens, writes a hold into the syntax tree and continues parsing.  Since it continues parsing, it can discover more parse errors.  Once parsing is done, all the parse errors can be printed and we exit.

However, the jsonnet parser doesn't have that capability, it just exits at the first error.  It would be nice to add this.  For example if you don't find an expected comma orclosing brace, you might just pretend that you saw one and keep going.  Not all syntax errors are recoverable so you still do need to exit part way through parsing, but you can try to recover from the most common ones.

It would be reasonable to only implement this in go-jsonnet since it would not introduce an incompatibility between the two implementations in terms of running Jsonnet code.


--
You received this message because you are subscribed to the Google Groups "Jsonnet" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jsonnet+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jsonnet/702fa13d-dfad-4055-8f93-75133a776131n%40googlegroups.com.

jer...@grafana.com

unread,
May 31, 2022, 2:59:27 AM5/31/22
to Jsonnet
I've implemented something like this internally:

```
local value = 3;

local test(actual, expected) =
  if actual == expected
  then null
  else actual + '!=' + expected;

local validate(tests) =
  if std.prune(tests) != {}
  then error std.manifestJsonEx(tests, '  ')
  else ['All tests succeeded.'];

local tests =
  std.prune(
    {
      'Test succeeds': test(value, 3),
      'Test fails': test(value, 4),
    }
  );

validate(tests)
```

Sandy Walsh

unread,
May 31, 2022, 10:45:09 AM5/31/22
to Jsonnet
Thanks Dave ... I was wondering if there was another token type like a <<placeholder>>, which wouldn't break parsing but we could just walk the placeholder tokens at the end? 

Dave Cunningham

unread,
May 31, 2022, 11:13:18 AM5/31/22
to Sandy Walsh, Jsonnet
Yes that's what I meant by "hole" except that I seem to have written "hold" instead, and it's not a token but an AST node.  You don't actually need to walk them in the end because you can simply accumulate errors as strings or whatever instead.

Sandy Walsh

unread,
May 31, 2022, 12:16:24 PM5/31/22
to Dave Cunningham, Jsonnet
Ah :) yes, that makes much more sense. Thanks, I'll mess with that. 

Stefan Zeiger

unread,
Jun 15, 2022, 10:16:22 AM6/15/22
to Sandy Walsh, Dave Cunningham, Jsonnet
We implemented warnings in Sjsonnet (https://github.com/databricks/sjsonnet/pull/132) to solve the same problem. It doesn't help with real parse errors that are hard to recover from but it can show you all missing identifiers instead of aborting after the first one. (We needed this feature because Sjsonnet was missing the required checks for invalid identifiers for a long time so we had accidentally ended up with many undetected problems in our codebase that would have had to be fixed one by one if we only had errors instead of warnings.)

Dave Cunningham

unread,
Jun 16, 2022, 8:20:48 AM6/16/22
to Stefan Zeiger, Sandy Walsh, Jsonnet
We could also do that. Both cpp and go Jsonnet do the static check so you wouldn't end up with undetected problems in your codebase, however if there are multiple problems it will only report the first one it sees.  It wouldn't be hard to accumulate errors while completing the static checking.

$ jsonnet -e 'local x = 1; z + y'
<cmdline>:1:14-15 Unknown variable: z

local x = 1; z + y

Reply all
Reply to author
Forward
0 new messages