-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Fix try/catch catches more than it should #1859 #2750
Fix try/catch catches more than it should #1859 #2750
Conversation
This is a straight-forward cherry-pick of ee36e9a from my old |
It does not matter much, but, probably because of the way you have |
😆 That's pretty funny. It's probably because I used |
15c5fbe
to
8a60d40
Compare
I think the issues above are fixed. |
8a60d40
to
6052fee
Compare
Here's a list of issues that this PR fixes. Hope some examples from there will be included. |
Here's also an example; |
@itchyny nice finds! I'll check them out and add tests based on them. |
Oh, that's ugly, |
|
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).
6052fee
to
db93945
Compare
@itchyny I think this is ready now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I merged fixing |
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:On backtrack through TRY_BEGIN it just backtracks.
If anything past the whole thing raises when 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 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).
Resolves #1859, resolves #1885, resolves #2140, resolves #2220, resolves #2485, resolves #2073.