Home | History | Annotate | Download | only in debug-promises
      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