Skip to content

Expose parser recover mode (collect syntax errors instead of throwing) #138

Open

Description

@aeberhart

Summary

JSONata JS supports jsonata(expr, { recover: true }): instead of throwing on the first syntax error, the parser records each error, puts a placeholder node in the tree, and keeps parsing. The caller gets a partial AST plus the full list of errors, which is useful for tooling such as editors, linters, and validation UIs.

The Java port has the plumbing, but users can't turn it on:

  • Parser.recover exists, but it is package-private and nothing sets it.
  • The constructor option is commented out in Jsonata: ast = parser.parse(expr);//, optionsRecover);
  • Jsonata.getErrors() exists and evaluate() already refuses to run expressions with errors ("Attempted to evaluate an expression containing syntax error(s)").

Proposal

  1. Add a recover flag to Jsonata.Options / OptionsBuilder and pass it through to the parser for that parse only. Because the parser is cached per thread (Jsonata.getParser()), the flag must not stay set for later parses on the same thread.
  2. Finish the recover paths in Parser:
    • Symbol.nud() returns a bare (error) symbol, and the JS code that records the error and remaining tokens is commented out.
    • handleError() returns an empty node (// FIXME node.error = err;), so the node doesn't point to its error.
  3. Port the recover-mode cases from the JSONata JS test suite (or add equivalent tests).

Prerequisite

The per-thread parser has to start every parse with a clean errors list (#135). Without that, one recover-mode parse with errors leaves its errors attached to every expression parsed later on the same thread, and evaluate() rejects valid expressions. This can be reproduced today by setting Jsonata.getParser().recover = true from a test in the same package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions