-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # 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.