node: mark promises as handled as soon as possible
authorVladimir Kurchatkin <vladimir.kurchatkin@gmail.com>
Thu, 11 Jun 2015 20:08:17 +0000 (23:08 +0300)
committerVladimir Kurchatkin <vladimir.kurchatkin@gmail.com>
Fri, 12 Jun 2015 21:24:24 +0000 (00:24 +0300)
Fixes: https://github.com/nodejs/io.js/issues/1912
PR-URL: https://github.com/nodejs/io.js/pull/1952
Reviewed-By: Domenic Denicola <d@domenic.me>
Reviewed-By: Petka Antonov <petka_antonov@hotmail.com>
src/node.js
test/parallel/test-promises-unhandled-rejections.js

index 2516478..292c7b2 100644 (file)
       var hasBeenNotified = hasBeenNotifiedProperty.get(promise);
       if (hasBeenNotified !== undefined) {
         hasBeenNotifiedProperty.delete(promise);
-        if (hasBeenNotified === true)
-          process.emit('rejectionHandled', promise);
+        if (hasBeenNotified === true) {
+          process.nextTick(function() {
+            process.emit('rejectionHandled', promise);
+          });
+        }
+
       }
     }
 
       if (event === promiseRejectEvent.unhandled)
         unhandledRejection(promise, reason);
       else if (event === promiseRejectEvent.handled)
-        process.nextTick(function() {
-          rejectionHandled(promise);
-        });
+        rejectionHandled(promise);
       else
         NativeModule.require('assert').fail('unexpected PromiseRejectEvent');
     });
index 9a186de..e5b3e6f 100644 (file)
@@ -275,6 +275,21 @@ asyncTest('Attaching a promise catch in a process.nextTick is soon enough to' +
   });
 });
 
+asyncTest('While inside setImmediate, catching a rejected promise derived ' +
+          'from returning a rejected promise in a fulfillment handler ' +
+          'prevents unhandledRejection', function(done) {
+  onUnhandledFail(done);
+
+  setImmediate(function() {
+    // reproduces on first tick and inside of setImmediate
+    Promise
+      .resolve('resolve')
+      .then(function() {
+        return Promise.reject('reject');
+      }).catch(function(e) {});
+  });
+});
+
 // State adapation tests
 asyncTest('catching a promise which is asynchronously rejected (via' +
           'resolution to an asynchronously-rejected promise) prevents' +