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

Fix handling of termination exceptions. #3029

Merged
merged 1 commit into from
Nov 1, 2024

Conversation

jp4a50
Copy link
Collaborator

@jp4a50 jp4a50 commented Oct 30, 2024

Exceptions caught in v8::TryCatch scopes need to be rethrown in order for the next try/catch handler down the stack to be notified of them. In some code paths, we rethrow the native jsg::JsExceptionThrown exception but don't rethrow the v8 exception using v8::TryCatch::ReThrow().

This commit fixes one such code path which resulted in IoContext::runImpl's jsg::JsExceptionThrown's catch block finding that the corresponding v8::TryCatch object hadn't been notified of the termination (and didn't contain an exception).

Exceptions caught in v8::TryCatch scopes need to be rethrown in order
for the next try/catch handler down the stack to be notified of them. In
some code paths, we rethrow the native jsg::JsExceptionThrown exception
but don't rethrow the v8 exception using v8::TryCatch::ReThrow().

This commit fixes one such code path which resulted in
IoContext::runImpl's jsg::JsExceptionThrown's catch block finding that
the corresponding v8::TryCatch object hadn't been notified of the
termination (and didn't contain an exception).
@jp4a50 jp4a50 requested review from a team as code owners October 30, 2024 16:57
@jp4a50
Copy link
Collaborator Author

jp4a50 commented Oct 30, 2024

Note that this change ensures that we now hit this conditional branch.

I wanted to generally prompt a discussion about how we want to handle various types of V8 exception, though. At the moment, it seems like our combination of v8::TryCatch and jsg::JsExceptionThrown is quite easy to misuse, leading to bugs like this.

Further context: we first started hitting this when we added this catch clause which allowed termination exceptions to bubble up to the try/catch in runImpl. I managed to find an internal test which repro'd the behaviour and debugged/verified the fix using it.

// This may happen in particular when the JsExceptionThrows was the result of
// TerminateException() but V8 has since cleared the terminate flag because all
// This may happen in particular when the JsExceptionThrown was the result of
// TerminateExecution() but V8 has since cleared the terminate flag because all
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jasnell what exactly is this comment referring to? Is it referencing this V8 logic here? I couldn't easily figure out under exactly what circumstances CallDepthIsZero() would be true since comments seemed to suggest that it pertains to "V8 API" call depth rather than JS call depth.

@jp4a50 jp4a50 merged commit 5089f1f into main Nov 1, 2024
13 checks passed
@jp4a50 jp4a50 deleted the jphillips/fix-empty-exception-log branch November 1, 2024 13:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants