1 // Copyright 2014 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Flags: --expose-debug-as debug --allow-natives-syntax --promise-extra 6 7 // Test debug events when a Promise is rejected, which is caught by a 8 // custom promise, which throws a new exception in its reject handler. 9 // We expect two Exception debug events: 10 // 1) when promise q is rejected. 11 // 2) when the custom reject closure in MyPromise throws an exception. 12 13 Debug = debug.Debug; 14 15 var expected_events = 1; 16 var log = []; 17 18 var p = new Promise(function(resolve, reject) { 19 log.push("resolve"); 20 resolve(); 21 }); 22 23 function MyPromise(resolver) { 24 var reject = function() { 25 log.push("throw in reject"); 26 throw new Error("reject"); // event 27 }; 28 var resolve = function() { }; 29 log.push("construct"); 30 resolver(resolve, reject); 31 }; 32 33 MyPromise.prototype = new Promise(function() {}); 34 p.constructor = MyPromise; 35 36 var q = p.chain( 37 function() { 38 log.push("reject caught"); 39 return Promise.reject(new Error("caught")); 40 }); 41 42 function listener(event, exec_state, event_data, data) { 43 try { 44 if (event == Debug.DebugEvent.Exception) { 45 expected_events--; 46 assertTrue(expected_events >= 0); 47 assertEquals("reject", event_data.exception().message); 48 // Assert that the debug event is triggered at the throw site. 49 assertTrue( 50 exec_state.frame(0).sourceLineText().indexOf("// event") > 0); 51 } 52 } catch (e) { 53 // Signal a failure with exit code 1. This is necessary since the 54 // debugger swallows exceptions and we expect the chained function 55 // and this listener to be executed after the main script is finished. 56 print("Unexpected exception: " + e + "\n" + e.stack); 57 quit(1); 58 } 59 } 60 61 Debug.setBreakOnUncaughtException(); 62 Debug.setListener(listener); 63 64 log.push("end main"); 65 66 function testDone(iteration) { 67 function checkResult() { 68 try { 69 assertTrue(iteration < 10); 70 if (expected_events === 0) { 71 assertEquals(["resolve", "construct", "end main", 72 "reject caught", "throw in reject"], log); 73 } else { 74 testDone(iteration + 1); 75 } 76 } catch (e) { 77 %AbortJS(e + "\n" + e.stack); 78 } 79 } 80 81 %EnqueueMicrotask(checkResult); 82 } 83 84 testDone(0); 85