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 an exception is thrown inside a Promise, which is 8 // caught by a custom promise, which throws a new exception in its reject 9 // handler. We expect two Exception debug events: 10 // 1) when the exception is thrown in the promise q. 11 // 2) when the custom reject closure in MyPromise throws an exception. 12 13 Debug = debug.Debug; 14 15 var expected_events = 2; 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 MyPromise.__proto__ = Promise; 35 p.constructor = MyPromise; 36 37 var q = p.chain( 38 function() { 39 log.push("throw caught"); 40 throw new Error("caught"); // event 41 }); 42 43 function listener(event, exec_state, event_data, data) { 44 try { 45 if (event == Debug.DebugEvent.Exception) { 46 expected_events--; 47 assertTrue(expected_events >= 0); 48 if (expected_events == 1) { 49 assertEquals(["resolve", "construct", "end main", 50 "throw caught"], log); 51 assertEquals("caught", event_data.exception().message); 52 } else if (expected_events == 0) { 53 assertEquals("reject", event_data.exception().message); 54 } else { 55 assertUnreachable(); 56 } 57 assertSame(q, event_data.promise()); 58 assertTrue(exec_state.frame(0).sourceLineText().indexOf('// event') > 0); 59 } 60 } catch (e) { 61 %AbortJS(e + "\n" + e.stack); 62 } 63 } 64 65 Debug.setBreakOnUncaughtException(); 66 Debug.setListener(listener); 67 68 log.push("end main"); 69 70 function testDone(iteration) { 71 function checkResult() { 72 try { 73 assertTrue(iteration < 10); 74 if (expected_events === 0) { 75 assertEquals(["resolve", "construct", "end main", 76 "throw caught", "throw in reject"], log); 77 } else { 78 testDone(iteration + 1); 79 } 80 } catch (e) { 81 %AbortJS(e + "\n" + e.stack); 82 } 83 } 84 85 %EnqueueMicrotask(checkResult); 86 } 87 88 testDone(0); 89