Revert "Trigger exception debug event for promises at the throw site."
This reverts r21092. R=ishell@chromium.org Review URL: https://codereview.chromium.org/262533009 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@21094 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
287f65aec9
commit
792af58115
@ -20,7 +20,8 @@ enum DebugEvent {
|
||||
BeforeCompile = 4,
|
||||
AfterCompile = 5,
|
||||
ScriptCollected = 6,
|
||||
BreakForCommand = 7
|
||||
PendingExceptionInPromise = 7,
|
||||
BreakForCommand = 8
|
||||
};
|
||||
|
||||
|
||||
|
@ -19,7 +19,8 @@ Debug.DebugEvent = { Break: 1,
|
||||
NewFunction: 3,
|
||||
BeforeCompile: 4,
|
||||
AfterCompile: 5,
|
||||
ScriptCollected: 6 };
|
||||
ScriptCollected: 6,
|
||||
PendingExceptionInPromise: 7 };
|
||||
|
||||
// Types of exceptions that can be broken upon.
|
||||
Debug.ExceptionBreak = { Caught : 0,
|
||||
|
64
src/debug.cc
64
src/debug.cc
@ -37,7 +37,6 @@ Debug::Debug(Isolate* isolate)
|
||||
disable_break_(false),
|
||||
break_on_exception_(false),
|
||||
break_on_uncaught_exception_(false),
|
||||
current_promise_catch_handler_(NULL),
|
||||
debug_break_return_(NULL),
|
||||
debug_break_slot_(NULL),
|
||||
isolate_(isolate) {
|
||||
@ -1319,53 +1318,6 @@ bool Debug::IsBreakOnException(ExceptionBreakType type) {
|
||||
}
|
||||
|
||||
|
||||
void Debug::PromiseHandlePrologue(Handle<JSFunction> promise_getter) {
|
||||
ASSERT(current_promise_getter_.is_null());
|
||||
current_promise_getter_ = Handle<JSFunction>::cast(
|
||||
isolate_->global_handles()->Create(*promise_getter));
|
||||
current_promise_catch_handler_ =
|
||||
StackHandler::FromAddress(Isolate::handler(isolate_->thread_local_top()));
|
||||
}
|
||||
|
||||
|
||||
void Debug::PromiseHandleEpilogue() {
|
||||
current_promise_catch_handler_ = NULL;
|
||||
Handle<Object> promise_getter;
|
||||
if (!current_promise_getter_.ToHandle(&promise_getter)) return;
|
||||
isolate_->global_handles()->Destroy(promise_getter.location());
|
||||
current_promise_getter_ = MaybeHandle<JSFunction>();
|
||||
}
|
||||
|
||||
|
||||
Handle<Object> Debug::GetPromiseForUncaughtException() {
|
||||
Handle<JSFunction> promise_getter;
|
||||
Handle<Object> undefined = isolate_->factory()->undefined_value();
|
||||
if (current_promise_getter_.ToHandle(&promise_getter)) {
|
||||
// Find the top-most try-catch handler.
|
||||
StackHandler* handler = StackHandler::FromAddress(
|
||||
Isolate::handler(isolate_->thread_local_top()));
|
||||
while (handler != NULL && !handler->is_catch()) {
|
||||
handler = handler->next();
|
||||
}
|
||||
#ifdef DEBUG
|
||||
// Make sure that our promise catch handler is in the list of handlers,
|
||||
// even if it's not the top-most try-catch handler.
|
||||
StackHandler* temp = handler;
|
||||
while (temp != current_promise_catch_handler_ && !temp->is_catch()) {
|
||||
temp = temp->next();
|
||||
CHECK(temp != NULL);
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
if (handler == current_promise_catch_handler_) {
|
||||
return Execution::Call(
|
||||
isolate_, promise_getter, undefined, 0, NULL).ToHandleChecked();
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
void Debug::PrepareStep(StepAction step_action,
|
||||
int step_count,
|
||||
StackFrame::Id frame_id) {
|
||||
@ -2695,7 +2647,9 @@ MaybeHandle<Object> Debugger::MakeScriptCollectedEvent(int id) {
|
||||
}
|
||||
|
||||
|
||||
void Debugger::OnException(Handle<Object> exception, bool uncaught) {
|
||||
void Debugger::OnException(Handle<Object> exception,
|
||||
bool uncaught,
|
||||
Handle<Object> promise) {
|
||||
HandleScope scope(isolate_);
|
||||
Debug* debug = isolate_->debug();
|
||||
|
||||
@ -2703,9 +2657,6 @@ void Debugger::OnException(Handle<Object> exception, bool uncaught) {
|
||||
if (debug->InDebugger()) return;
|
||||
if (!Debugger::EventActive(v8::Exception)) return;
|
||||
|
||||
Handle<Object> promise = debug->GetPromiseForUncaughtException();
|
||||
uncaught |= !promise->IsUndefined();
|
||||
|
||||
// Bail out if exception breaks are not active
|
||||
if (uncaught) {
|
||||
// Uncaught exceptions are reported by either flags.
|
||||
@ -2723,6 +2674,10 @@ void Debugger::OnException(Handle<Object> exception, bool uncaught) {
|
||||
// Clear all current stepping setup.
|
||||
debug->ClearStepping();
|
||||
|
||||
// Determine event;
|
||||
DebugEvent event = promise->IsUndefined()
|
||||
? v8::Exception : v8::PendingExceptionInPromise;
|
||||
|
||||
// Create the event data object.
|
||||
Handle<Object> event_data;
|
||||
// Bail out and don't call debugger if exception.
|
||||
@ -2732,7 +2687,7 @@ void Debugger::OnException(Handle<Object> exception, bool uncaught) {
|
||||
}
|
||||
|
||||
// Process debug event.
|
||||
ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false);
|
||||
ProcessDebugEvent(event, Handle<JSObject>::cast(event_data), false);
|
||||
// Return to continue execution from where the exception was thrown.
|
||||
}
|
||||
|
||||
@ -3214,8 +3169,7 @@ void Debugger::SetMessageHandler(v8::Debug::MessageHandler2 handler) {
|
||||
|
||||
|
||||
void Debugger::ListenersChanged() {
|
||||
bool active = IsDebuggerActive();
|
||||
if (active) {
|
||||
if (IsDebuggerActive()) {
|
||||
// Disable the compilation cache when the debugger is active.
|
||||
isolate_->compilation_cache()->Disable();
|
||||
debugger_unload_pending_ = false;
|
||||
|
17
src/debug.h
17
src/debug.h
@ -235,12 +235,6 @@ class Debug {
|
||||
void FloodHandlerWithOneShot();
|
||||
void ChangeBreakOnException(ExceptionBreakType type, bool enable);
|
||||
bool IsBreakOnException(ExceptionBreakType type);
|
||||
|
||||
void PromiseHandlePrologue(Handle<JSFunction> promise_getter);
|
||||
void PromiseHandleEpilogue();
|
||||
// Returns a promise if it does not have a reject handler.
|
||||
Handle<Object> GetPromiseForUncaughtException();
|
||||
|
||||
void PrepareStep(StepAction step_action,
|
||||
int step_count,
|
||||
StackFrame::Id frame_id);
|
||||
@ -544,13 +538,6 @@ class Debug {
|
||||
bool break_on_exception_;
|
||||
bool break_on_uncaught_exception_;
|
||||
|
||||
// When a promise is being resolved, we may want to trigger a debug event for
|
||||
// the case we catch a throw. For this purpose we remember the try-catch
|
||||
// handler address that would catch the exception. We also hold onto a
|
||||
// closure that returns a promise if the exception is considered uncaught.
|
||||
StackHandler* current_promise_catch_handler_;
|
||||
MaybeHandle<JSFunction> current_promise_getter_;
|
||||
|
||||
// Per-thread data.
|
||||
class ThreadLocal {
|
||||
public:
|
||||
@ -787,7 +774,9 @@ class Debugger {
|
||||
MUST_USE_RESULT MaybeHandle<Object> MakeScriptCollectedEvent(int id);
|
||||
|
||||
void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue);
|
||||
void OnException(Handle<Object> exception, bool uncaught);
|
||||
void OnException(Handle<Object> exception,
|
||||
bool uncaught,
|
||||
Handle<Object> promise = Handle<Object>::null());
|
||||
void OnBeforeCompile(Handle<Script> script);
|
||||
|
||||
enum AfterCompileFlags {
|
||||
|
@ -1031,7 +1031,8 @@ void Isolate::DoThrow(Object* exception, MessageLocation* location) {
|
||||
|
||||
// Notify debugger of exception.
|
||||
if (catchable_by_javascript) {
|
||||
debugger_->OnException(exception_handle, report_exception);
|
||||
debugger_->OnException(
|
||||
exception_handle, report_exception, factory()->undefined_value());
|
||||
}
|
||||
|
||||
// Generate the message if required.
|
||||
|
@ -1186,7 +1186,7 @@ inherits(PromiseMirror, ObjectMirror);
|
||||
|
||||
|
||||
PromiseMirror.prototype.status = function() {
|
||||
var status = builtins.GetPromiseStatus(this.value_);
|
||||
var status = %GetPromiseStatus(this.value_);
|
||||
if (status == 0) return "pending";
|
||||
if (status == 1) return "resolved";
|
||||
return "rejected";
|
||||
@ -1194,7 +1194,7 @@ PromiseMirror.prototype.status = function() {
|
||||
|
||||
|
||||
PromiseMirror.prototype.promiseValue = function() {
|
||||
return builtins.GetPromiseValue(this.value_);
|
||||
return %GetPromiseValue(this.value_);
|
||||
};
|
||||
|
||||
|
||||
|
@ -35,13 +35,10 @@ function Promise(resolver) {
|
||||
throw MakeTypeError('resolver_not_a_function', [resolver]);
|
||||
var promise = PromiseInit(this);
|
||||
try {
|
||||
%DebugPromiseHandlePrologue(function() { return promise });
|
||||
resolver(function(x) { PromiseResolve(promise, x) },
|
||||
function(r) { PromiseReject(promise, r) });
|
||||
} catch (e) {
|
||||
PromiseReject(promise, e);
|
||||
} finally {
|
||||
%DebugPromiseHandleEpilogue();
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,11 +161,6 @@ function PromiseEnqueue(value, tasks) {
|
||||
|
||||
function PromiseHandle(value, handler, deferred) {
|
||||
try {
|
||||
%DebugPromiseHandlePrologue(
|
||||
function() {
|
||||
var queue = GET_PRIVATE(deferred.promise, promiseOnReject);
|
||||
return (queue && queue.length == 0) ? deferred.promise : UNDEFINED;
|
||||
});
|
||||
var result = handler(value);
|
||||
if (result === deferred.promise)
|
||||
throw MakeTypeError('promise_cyclic', [result]);
|
||||
@ -177,13 +169,21 @@ function PromiseHandle(value, handler, deferred) {
|
||||
else
|
||||
deferred.resolve(result);
|
||||
} catch (exception) {
|
||||
var uncaught = false;
|
||||
var reject_queue = GET_PRIVATE(deferred.promise, promiseOnReject);
|
||||
if (reject_queue && reject_queue.length == 0) {
|
||||
// The deferred promise may get a reject handler attached later.
|
||||
// For now, we consider the exception to be (for the moment) uncaught.
|
||||
uncaught = true;
|
||||
}
|
||||
try {
|
||||
%DebugPromiseHandleEpilogue(); // Match the previous prologue.
|
||||
%DebugPromiseHandlePrologue(function() { return deferred.promise });
|
||||
deferred.reject(exception);
|
||||
} catch (e) { }
|
||||
} finally {
|
||||
%DebugPromiseHandleEpilogue();
|
||||
} catch (e) {
|
||||
// The reject handler can only throw for a custom deferred promise.
|
||||
// We consider the original exception to be uncaught.
|
||||
uncaught = true;
|
||||
}
|
||||
if (uncaught) %DebugPendingExceptionInPromise(exception, deferred.promise);
|
||||
}
|
||||
}
|
||||
|
||||
@ -321,6 +321,14 @@ function GetPromiseStatus(promise) {
|
||||
return GET_PRIVATE(promise, promiseStatus);
|
||||
}
|
||||
|
||||
function GetPromiseOnResolve(promise) {
|
||||
return GET_PRIVATE(promise, promiseOnResolve);
|
||||
}
|
||||
|
||||
function GetPromiseOnReject(promise) {
|
||||
return GET_PRIVATE(promise, promiseOnReject);
|
||||
}
|
||||
|
||||
function GetPromiseValue(promise) {
|
||||
return GET_PRIVATE(promise, promiseValue);
|
||||
}
|
||||
|
@ -5657,22 +5657,13 @@ RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) {
|
||||
}
|
||||
|
||||
|
||||
// The argument is a closure that is kept until the epilogue is called.
|
||||
// On exception, the closure is called, which returns the promise if the
|
||||
// exception is considered uncaught, or undefined otherwise.
|
||||
RUNTIME_FUNCTION(Runtime_DebugPromiseHandlePrologue) {
|
||||
ASSERT(args.length() == 1);
|
||||
// Notify the debugger if an expcetion in a promise is not caught (yet).
|
||||
RUNTIME_FUNCTION(Runtime_DebugPendingExceptionInPromise) {
|
||||
ASSERT(args.length() == 2);
|
||||
HandleScope scope(isolate);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSFunction, promise_getter, 0);
|
||||
isolate->debug()->PromiseHandlePrologue(promise_getter);
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_DebugPromiseHandleEpilogue) {
|
||||
ASSERT(args.length() == 0);
|
||||
SealHandleScope shs(isolate);
|
||||
isolate->debug()->PromiseHandleEpilogue();
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, exception, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 1);
|
||||
isolate->debugger()->OnException(exception, true, promise);
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
|
@ -75,8 +75,7 @@ namespace internal {
|
||||
F(SetInlineBuiltinFlag, 1, 1) \
|
||||
F(StoreArrayLiteralElement, 5, 1) \
|
||||
F(DebugPrepareStepInIfStepping, 1, 1) \
|
||||
F(DebugPromiseHandlePrologue, 1, 1) \
|
||||
F(DebugPromiseHandleEpilogue, 0, 1) \
|
||||
F(DebugPendingExceptionInPromise, 2, 1) \
|
||||
F(FlattenString, 1, 1) \
|
||||
F(LoadMutableDouble, 2, 1) \
|
||||
F(TryMigrateInstance, 1, 1) \
|
||||
|
@ -6,7 +6,8 @@
|
||||
|
||||
// Test debug events when we listen to all exceptions and
|
||||
// there is a catch handler for the exception thrown in a Promise.
|
||||
// We expect a normal Exception debug event to be triggered.
|
||||
// Expectation:
|
||||
// - only the normal Exception debug event is triggered.
|
||||
|
||||
Debug = debug.Debug;
|
||||
|
||||
@ -34,10 +35,10 @@ function listener(event, exec_state, event_data, data) {
|
||||
// Ignore exceptions during startup in stress runs.
|
||||
if (step >= 1) return;
|
||||
assertEquals(["resolve", "end main", "throw"], log);
|
||||
assertTrue(event != Debug.DebugEvent.PendingExceptionInPromise);
|
||||
if (event == Debug.DebugEvent.Exception) {
|
||||
assertEquals("caught", event_data.exception().message);
|
||||
assertEquals(undefined, event_data.promise());
|
||||
assertFalse(event_data.uncaught());
|
||||
step++;
|
||||
}
|
||||
} catch (e) {
|
||||
|
@ -1,38 +0,0 @@
|
||||
// Copyright 2014 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony-promises --expose-debug-as debug
|
||||
|
||||
// Test debug events when we only listen to uncaught exceptions, the Promise
|
||||
// throws, and a catch handler is installed right before throwing.
|
||||
// We expect no debug event to be triggered.
|
||||
|
||||
Debug = debug.Debug;
|
||||
|
||||
var p = new Promise(function(resolve, reject) {
|
||||
resolve();
|
||||
});
|
||||
|
||||
var q = p.chain(
|
||||
function() {
|
||||
q.catch(function(e) {
|
||||
assertEquals("caught", e.message);
|
||||
});
|
||||
throw new Error("caught");
|
||||
});
|
||||
|
||||
function listener(event, exec_state, event_data, data) {
|
||||
try {
|
||||
assertTrue(event != Debug.DebugEvent.Exception);
|
||||
} catch (e) {
|
||||
// Signal a failure with exit code 1. This is necessary since the
|
||||
// debugger swallows exceptions and we expect the chained function
|
||||
// and this listener to be executed after the main script is finished.
|
||||
print("Unexpected exception: " + e + "\n" + e.stack);
|
||||
quit(1);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.setBreakOnUncaughtException();
|
||||
Debug.setListener(listener);
|
@ -6,7 +6,8 @@
|
||||
|
||||
// Test debug events when we only listen to uncaught exceptions and
|
||||
// there is a catch handler for the exception thrown in a Promise.
|
||||
// We expect no debug event to be triggered.
|
||||
// Expectation:
|
||||
// - no debug event is triggered.
|
||||
|
||||
Debug = debug.Debug;
|
||||
|
||||
@ -27,6 +28,7 @@ q.catch(
|
||||
function listener(event, exec_state, event_data, data) {
|
||||
try {
|
||||
assertTrue(event != Debug.DebugEvent.Exception);
|
||||
assertTrue(event != Debug.DebugEvent.PendingExceptionInPromise);
|
||||
} catch (e) {
|
||||
// Signal a failure with exit code 1. This is necessary since the
|
||||
// debugger swallows exceptions and we expect the chained function
|
||||
|
@ -1,46 +0,0 @@
|
||||
// Copyright 2014 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony-promises --expose-debug-as debug
|
||||
|
||||
// Test debug events when we only listen to uncaught exceptions and
|
||||
// an exception is thrown in the the Promise constructor.
|
||||
// We expect an Exception debug event with a promise to be triggered.
|
||||
|
||||
Debug = debug.Debug;
|
||||
|
||||
var step = 0;
|
||||
var exception = null;
|
||||
|
||||
function listener(event, exec_state, event_data, data) {
|
||||
try {
|
||||
// Ignore exceptions during startup in stress runs.
|
||||
if (step >= 1) return;
|
||||
if (event == Debug.DebugEvent.Exception) {
|
||||
assertEquals(0, step);
|
||||
assertEquals("uncaught", event_data.exception().message);
|
||||
assertTrue(event_data.promise() instanceof Promise);
|
||||
assertTrue(event_data.uncaught());
|
||||
// Assert that the debug event is triggered at the throw site.
|
||||
assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
|
||||
step++;
|
||||
}
|
||||
} catch (e) {
|
||||
// Signal a failure with exit code 1. This is necessary since the
|
||||
// debugger swallows exceptions and we expect the chained function
|
||||
// and this listener to be executed after the main script is finished.
|
||||
print("Unexpected exception: " + e + "\n" + e.stack);
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.setBreakOnUncaughtException();
|
||||
Debug.setListener(listener);
|
||||
|
||||
var p = new Promise(function(resolve, reject) {
|
||||
throw new Error("uncaught"); // event
|
||||
});
|
||||
|
||||
assertEquals(1, step);
|
||||
assertNull(exception);
|
@ -6,7 +6,7 @@
|
||||
|
||||
// Test debug events when an exception is thrown inside a Promise, which is
|
||||
// caught by a custom promise, which throws a new exception in its reject
|
||||
// handler. We expect an Exception debug event with a promise to be triggered.
|
||||
// handler. We expect a PendingExceptionInPromise event to be triggered.
|
||||
|
||||
Debug = debug.Debug;
|
||||
|
||||
@ -21,7 +21,7 @@ var p = new Promise(function(resolve, reject) {
|
||||
function MyPromise(resolver) {
|
||||
var reject = function() {
|
||||
log.push("throw reject");
|
||||
throw new Error("reject"); // event
|
||||
throw new Error("reject");
|
||||
};
|
||||
var resolve = function() { };
|
||||
log.push("construct");
|
||||
@ -39,12 +39,12 @@ var q = p.chain(
|
||||
|
||||
function listener(event, exec_state, event_data, data) {
|
||||
try {
|
||||
if (event == Debug.DebugEvent.Exception) {
|
||||
if (event == Debug.DebugEvent.PendingExceptionInPromise) {
|
||||
assertEquals(["resolve", "construct", "end main",
|
||||
"throw caught", "throw reject"], log);
|
||||
assertEquals("reject", event_data.exception().message);
|
||||
assertEquals(q, event_data.promise());
|
||||
assertTrue(exec_state.frame(0).sourceLineText().indexOf('// event') > 0);
|
||||
assertEquals("caught", event_data.exception().message);
|
||||
} else if (event == Debug.DebugEvent.Exception) {
|
||||
assertUnreachable();
|
||||
}
|
||||
} catch (e) {
|
||||
// Signal a failure with exit code 1. This is necessary since the
|
||||
|
@ -6,7 +6,10 @@
|
||||
|
||||
// Test debug events when we listen to all exceptions and
|
||||
// there is a catch handler for the exception thrown in a Promise.
|
||||
// We expect an Exception debug event with a promise to be triggered.
|
||||
// Expectation:
|
||||
// - the normal Exception debug event is triggered.
|
||||
// - the PendingExceptionInPromise debug event is triggered afterwards,
|
||||
// with the same exception object.
|
||||
|
||||
Debug = debug.Debug;
|
||||
|
||||
@ -22,24 +25,28 @@ var p = new Promise(function(resolve, reject) {
|
||||
var q = p.chain(
|
||||
function() {
|
||||
log.push("throw");
|
||||
throw new Error("uncaught"); // event
|
||||
throw new Error("uncaught");
|
||||
});
|
||||
|
||||
function listener(event, exec_state, event_data, data) {
|
||||
try {
|
||||
// Ignore exceptions during startup in stress runs.
|
||||
if (step >= 1) return;
|
||||
if (step > 1) return;
|
||||
assertEquals(["resolve", "end main", "throw"], log);
|
||||
if (event == Debug.DebugEvent.Exception) {
|
||||
assertEquals(0, step);
|
||||
assertEquals("uncaught", event_data.exception().message);
|
||||
exception = event_data.exception();
|
||||
assertEquals(undefined, event_data.promise());
|
||||
} else if (event == Debug.DebugEvent.PendingExceptionInPromise) {
|
||||
assertEquals(1, step);
|
||||
assertEquals(exception, event_data.exception());
|
||||
assertEquals("uncaught", exception.message);
|
||||
assertTrue(event_data.promise() instanceof Promise);
|
||||
assertEquals(q, event_data.promise());
|
||||
assertTrue(event_data.uncaught());
|
||||
// Assert that the debug event is triggered at the throw site.
|
||||
assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
|
||||
step++;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
step++;
|
||||
} catch (e) {
|
||||
// Signal a failure with exit code 1. This is necessary since the
|
||||
// debugger swallows exceptions and we expect the chained function
|
||||
|
@ -6,7 +6,8 @@
|
||||
|
||||
// Test debug events when we only listen to uncaught exceptions and
|
||||
// there is a catch handler for the exception thrown in a Promise.
|
||||
// We expect an Exception debug event with a promise to be triggered.
|
||||
// Expectation:
|
||||
// - only the PendingExceptionInPromise debug event is triggered.
|
||||
|
||||
Debug = debug.Debug;
|
||||
|
||||
@ -21,7 +22,7 @@ var p = new Promise(function(resolve, reject) {
|
||||
var q = p.chain(
|
||||
function() {
|
||||
log.push("throw");
|
||||
throw new Error("uncaught"); // event
|
||||
throw new Error("uncaught");
|
||||
});
|
||||
|
||||
function listener(event, exec_state, event_data, data) {
|
||||
@ -30,13 +31,12 @@ function listener(event, exec_state, event_data, data) {
|
||||
if (step >= 1) return;
|
||||
assertEquals(["resolve", "end main", "throw"], log);
|
||||
if (event == Debug.DebugEvent.Exception) {
|
||||
assertUnreachable();
|
||||
} else if (event == Debug.DebugEvent.PendingExceptionInPromise) {
|
||||
assertEquals(0, step);
|
||||
assertEquals("uncaught", event_data.exception().message);
|
||||
assertTrue(event_data.promise() instanceof Promise);
|
||||
assertEquals(q, event_data.promise());
|
||||
assertTrue(event_data.uncaught());
|
||||
// Assert that the debug event is triggered at the throw site.
|
||||
assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
|
||||
step++;
|
||||
}
|
||||
} catch (e) {
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
// Test debug events when an exception is thrown inside a Promise, which is
|
||||
// caught by a custom promise, which has no reject handler.
|
||||
// We expect an Exception event with a promise to be triggered.
|
||||
// We expect a PendingExceptionInPromise event to be triggered.
|
||||
|
||||
Debug = debug.Debug;
|
||||
|
||||
@ -31,16 +31,16 @@ p.constructor = MyPromise;
|
||||
var q = p.chain(
|
||||
function() {
|
||||
log.push("throw caught");
|
||||
throw new Error("caught"); // event
|
||||
throw new Error("caught");
|
||||
});
|
||||
|
||||
function listener(event, exec_state, event_data, data) {
|
||||
try {
|
||||
if (event == Debug.DebugEvent.Exception) {
|
||||
if (event == Debug.DebugEvent.PendingExceptionInPromise) {
|
||||
assertEquals(["resolve", "construct", "end main", "throw caught"], log);
|
||||
assertEquals("undefined is not a function",
|
||||
event_data.exception().message);
|
||||
assertEquals(q, event_data.promise());
|
||||
assertEquals("caught", event_data.exception().message);
|
||||
} else if (event == Debug.DebugEvent.Exception) {
|
||||
assertUnreachable();
|
||||
}
|
||||
} catch (e) {
|
||||
// Signal a failure with exit code 1. This is necessary since the
|
||||
|
Loading…
Reference in New Issue
Block a user