Skip to content
This repository has been archived by the owner on Oct 15, 2020. It is now read-only.

Commit

Permalink
chakrashim: let caller TryCatch record exception
Browse files Browse the repository at this point in the history
It's possible a caller uses TryCatch, call an external function which
throws an exception, then continue to make other calls to script engine.
The exception is supposed to be caught by the TryCatch.

Fixes `test-async-wrap-throw-from-callback` on node-chakracore.

PR-URL: #54
Reviewed-By: Sandeep Agarwal <Agarwal.Sandeep@microsoft.com>
  • Loading branch information
Jianchun Xu committed Apr 13, 2016
1 parent 53c2d8e commit 41d9652
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 3 deletions.
2 changes: 2 additions & 0 deletions deps/chakrashim/include/v8.h
Original file line number Diff line number Diff line change
Expand Up @@ -2350,12 +2350,14 @@ class V8_EXPORT TryCatch {
private:
friend class Function;

void SetNonUser() { user = false; }
void GetAndClearException();
void CheckReportExternalException();

JsValueRef error;
TryCatch* prev;
bool rethrow;
bool user;
bool verbose;
};

Expand Down
1 change: 1 addition & 0 deletions deps/chakrashim/src/v8function.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ MaybeLocal<Value> Function::Call(Local<Context> context,
JsValueRef result;
{
TryCatch tryCatch;
tryCatch.SetNonUser();
if (JsCallFunction((JsValueRef)this, args, argc + 1,
&result) != JsNoError) {
tryCatch.CheckReportExternalException();
Expand Down
14 changes: 11 additions & 3 deletions deps/chakrashim/src/v8trycatch.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ namespace v8 {
TryCatch::TryCatch(Isolate* isolate)
: error(JS_INVALID_REFERENCE),
rethrow(false),
user(true),
verbose(false) {
jsrt::IsolateShim * isolateShim = jsrt::IsolateShim::GetCurrent();
prev = isolateShim->tryCatchStackTop;
Expand Down Expand Up @@ -156,13 +157,20 @@ void TryCatch::SetVerbose(bool value) {
}

void TryCatch::CheckReportExternalException() {
// Let caller TryCatch record the exception
TryCatch* tryCatch = (prev != nullptr && prev->user) ? prev : this;
if (tryCatch == prev) {
tryCatch->GetAndClearException();
}

// This is only used by Function::Call. If caller does not use TryCatch to
// handle external exceptions, or uses a TryCatch and SetVerbose(),
// we'll report the external exception message (triggers uncaughtException).
if (prev == nullptr || prev->verbose) {
jsrt::IsolateShim::GetCurrent()->ForEachMessageListener([this](
void * messageListener) {
((v8::MessageCallback)messageListener)(Message(), Exception());
jsrt::IsolateShim::GetCurrent()->ForEachMessageListener(
[tryCatch](void * messageListener) {
((v8::MessageCallback)messageListener)(tryCatch->Message(),
tryCatch->Exception());
});
} else {
rethrow = true; // Otherwise leave the exception as is
Expand Down

0 comments on commit 41d9652

Please sign in to comment.