Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strange behaviour when using two piped try catch error #2485

Closed
wader opened this issue Sep 14, 2022 · 0 comments · Fixed by #2750
Closed

Strange behaviour when using two piped try catch error #2485

wader opened this issue Sep 14, 2022 · 0 comments · Fixed by #2750
Labels

Comments

@wader
Copy link
Member

wader commented Sep 14, 2022

Describe the bug

When having two piped try/catch the catch for the first try seems to be executed even thought its try expression did not throw an error.

To Reproduce

# current jq master (cff5336)
$ jq --version
jq-1.6-159-gcff5336

$ jq -n 'try null catch error(["catch-a", .]) | try error("error-b") catch error(["catch-b", .])'
jq: error (at <unknown>) (not a string): ["catch-a",["catch-b","error-b"]]

Expected behavior

gojq has the behavior i would expect

$ gojq -n 'try null catch error(["catch-a", .]) | try error("error-b") catch error(["catch-b", .])'
gojq: error: ["catch-b","error-b"]

Additional context

Possibly related to #1859

@itchyny itchyny added the bug label Jun 3, 2023
nicowilliams added a commit to nicowilliams/jq that referenced this issue Jul 24, 2023
Close jqlang#1885, jqlang#2140, jqlang#2011, jqlang#2220, jqlang#2485, 2073

Rename the FORK_OPT opcode to TRY_BEGIN, add a TRY_END opcode, and wrap
errors when raising through a TRY_END so that they will not be caught by
the matching TRY_BEGIN.

Now a `try exp catch handler` expression generates code like:

    TRY_BEGIN handler
    <exp>
    TRY_END
    JUMP past_handler
    handler: <handler>
    past_handler:
    ...

On backtrack through TRY_BEGIN it just backtracks.

If anything past the whole thing raises when <exp> produced a value,
then the TRY_END will catch the error, wrap it in another, and
backtrack.  The TRY_BEGIN will see a wrapped error and then it will
unwrap and re-raise the error.

If <exp> raises, then TRY_BEGIN will catch the error and jump to the
handler, but the TRY_BEGIN will not stack_save() in that case, so on
raise/backtrack the TRY_BEGIN will not execute again (nor will the
TRY_END).
emanuele6 pushed a commit that referenced this issue Jul 24, 2023
Close #1885, #2140, #2011, #2220, #2485, #2073

Rename the FORK_OPT opcode to TRY_BEGIN, add a TRY_END opcode, and wrap
errors when raising through a TRY_END so that they will not be caught by
the matching TRY_BEGIN.

Now a `try exp catch handler` expression generates code like:

    TRY_BEGIN handler
    <exp>
    TRY_END
    JUMP past_handler
    handler: <handler>
    past_handler:
    ...

On backtrack through TRY_BEGIN it just backtracks.

If anything past the whole thing raises when <exp> produced a value,
then the TRY_END will catch the error, wrap it in another, and
backtrack.  The TRY_BEGIN will see a wrapped error and then it will
unwrap and re-raise the error.

If <exp> raises, then TRY_BEGIN will catch the error and jump to the
handler, but the TRY_BEGIN will not stack_save() in that case, so on
raise/backtrack the TRY_BEGIN will not execute again (nor will the
TRY_END).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants