// Copyright 2016 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: --ignore-unhandled-promises Debug = debug.Debug var exception = null; var log; function listener(event, exec_state, event_data, data) { if (event != Debug.DebugEvent.Exception) return; try { var line = exec_state.frame(0).sourceLineText(); var match = /Exception (\w)/.exec(line); assertNotNull(match); log.push(match[1]); } catch (e) { exception = e; } } async function thrower() { throw "a"; // Exception a } async function caught_throw() { try { await thrower(); } catch (e) { assertEquals("a", e); } } // Caught throw, events on any exception. log = []; Debug.setListener(listener); Debug.setBreakOnException(); caught_throw(); %PerformMicrotaskCheckpoint(); Debug.setListener(null); Debug.clearBreakOnException(); assertEquals(["a"], log); assertNull(exception); // Caught throw, events on uncaught exception. log = []; Debug.setListener(listener); Debug.setBreakOnUncaughtException(); caught_throw(); %PerformMicrotaskCheckpoint(); Debug.setListener(null); Debug.clearBreakOnUncaughtException(); assertEquals([], log); assertNull(exception); var reject = Promise.reject("b"); async function caught_reject() { try { await reject; } catch (e) { assertEquals("b", e); } } // Caught reject, events on any exception. log = []; Debug.setListener(listener); Debug.setBreakOnException(); caught_reject(); %PerformMicrotaskCheckpoint(); Debug.setListener(null); Debug.clearBreakOnException(); assertEquals([], log); assertNull(exception); // Caught reject, events on uncaught exception. log = []; Debug.setListener(listener); Debug.setBreakOnUncaughtException(); caught_reject(); %PerformMicrotaskCheckpoint(); Debug.setListener(null); Debug.clearBreakOnUncaughtException(); assertEquals([], log); assertNull(exception); log = []; Debug.setListener(listener); Debug.setBreakOnException(); // "rethrown" uncaught exceptions in return don't cause another event async function propagate_inner() { return thrower(); } async function propagate_outer() { return propagate_inner(); } propagate_outer(); %PerformMicrotaskCheckpoint(); assertEquals(["a"], log); assertNull(exception); // Also don't propagate if an await interceded log = []; async function propagate_await() { await 1; return thrower(); } async function propagate_await_outer() { return propagate_await(); } propagate_await_outer(); %PerformMicrotaskCheckpoint(); assertEquals(["a"], log); assertNull(exception); Debug.clearBreakOnException(); Debug.setBreakOnUncaughtException(); log = []; Promise.resolve().then(() => Promise.reject()).catch(() => log.push("d")); // Exception c %PerformMicrotaskCheckpoint(); assertEquals(["d"], log); assertNull(exception); Debug.clearBreakOnUncaughtException(); Debug.setListener(null); // If devtools is turned on in the middle, then catch prediction // could be wrong (here, it mispredicts the exception as caught), // but shouldn't crash. log = []; var resolve; var turnOnListenerPromise = new Promise(r => resolve = r); async function confused() { await turnOnListenerPromise; throw foo } confused(); Promise.resolve().then(() => { Debug.setListener(listener); Debug.setBreakOnUncaughtException(); resolve(); }); assertEquals([], log);