Skip to content

Commit eb9295b

Browse files
benjamingrcodebytere
authored andcommitted
promise: emit error on domain unhandled rejections
PR-URL: #36082 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
1 parent 89da0c3 commit eb9295b

3 files changed

Lines changed: 24 additions & 33 deletions

File tree

‎lib/internal/process/promises.js‎

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ function unhandledRejection(promise, reason) {
117117
maybeUnhandledPromises.set(promise,{
118118
reason,
119119
uid: ++lastPromiseId,
120-
warned: false
120+
warned: false,
121+
domain: process.domain
121122
});
122123
// This causes the promise to be referenced at least for one tick.
123124
pendingUnhandledRejections.push(promise);
@@ -192,26 +193,32 @@ function processPromiseRejections() {
192193
}
193194
promiseInfo.warned=true;
194195
const{ reason, uid }=promiseInfo;
196+
functionemit(reason,promise,promiseInfo){
197+
if(promiseInfo.domain){
198+
returnpromiseInfo.domain.emit('error',reason);
199+
}
200+
returnprocess.emit('unhandledRejection',reason,promise);
201+
}
195202
switch(unhandledRejectionsMode){
196203
casekStrictUnhandledRejections: {
197204
consterr=reasoninstanceofError ?
198205
reason : generateUnhandledRejectionError(reason);
199206
triggerUncaughtException(err,true/* fromPromise */);
200-
consthandled=process.emit('unhandledRejection',reason,promise);
207+
consthandled=emit(reason,promise,promiseInfo);
201208
if(!handled)emitUnhandledRejectionWarning(uid,reason);
202209
break;
203210
}
204211
casekIgnoreUnhandledRejections: {
205-
process.emit('unhandledRejection',reason,promise);
212+
emit(reason,promise,promiseInfo);
206213
break;
207214
}
208215
casekAlwaysWarnUnhandledRejections: {
209-
process.emit('unhandledRejection',reason,promise);
216+
emit(reason,promise,promiseInfo);
210217
emitUnhandledRejectionWarning(uid,reason);
211218
break;
212219
}
213220
casekThrowUnhandledRejections: {
214-
consthandled=process.emit('unhandledRejection',reason,promise);
221+
consthandled=emit(reason,promise,promiseInfo);
215222
if(!handled){
216223
consterr=reasoninstanceofError ?
217224
reason : generateUnhandledRejectionError(reason);
@@ -220,7 +227,7 @@ function processPromiseRejections() {
220227
break;
221228
}
222229
casekWarnWithErrorCodeUnhandledRejections: {
223-
consthandled=process.emit('unhandledRejection',reason,promise);
230+
consthandled=emit(reason,promise,promiseInfo);
224231
if(!handled){
225232
emitUnhandledRejectionWarning(uid,reason);
226233
process.exitCode=1;
@@ -266,10 +273,9 @@ function generateUnhandledRejectionError(reason) {
266273
functionlistenForRejections(){
267274
setPromiseRejectCallback(promiseRejectHandler);
268275
}
269-
270276
module.exports={
271277
hasRejectionToWarn,
272278
setHasRejectionToWarn,
273279
listenForRejections,
274-
processPromiseRejections
280+
processPromiseRejections,
275281
};

‎test/parallel/test-domain-promise.js‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,13 @@ process.on('warning', common.mustNotCall());
126126
}));
127127
}));
128128
}
129+
{
130+
// Unhandled rejections become errors on the domain
131+
constd=domain.create();
132+
d.on('error',common.mustCall((e)=>{
133+
assert.strictEqual(e.message,'foo');
134+
}));
135+
d.run(common.mustCall(()=>{
136+
Promise.reject(newError('foo'));
137+
}));
138+
}

‎test/parallel/test-promises-unhandled-rejections.js‎

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22
constcommon=require('../common');
33
constassert=require('assert');
4-
constdomain=require('domain');
54
const{ inspect }=require('util');
65

76
common.disableCrashOnUnhandledRejection();
@@ -622,30 +621,6 @@ asyncTest('setImmediate + promise microtasks is too late to attach a catch' +
622621
});
623622
});
624623

625-
asyncTest(
626-
'Promise unhandledRejection handler does not interfere with domain'+
627-
' error handlers being given exceptions thrown from nextTick.',
628-
function(done){
629-
constd=domain.create();
630-
letdomainReceivedError;
631-
d.on('error',function(e){
632-
domainReceivedError=e;
633-
});
634-
d.run(function(){
635-
conste=newError('error');
636-
constdomainError=newError('domain error');
637-
onUnhandledSucceed(done,function(reason,promise){
638-
assert.strictEqual(reason,e);
639-
assert.strictEqual(domainReceivedError,domainError);
640-
});
641-
Promise.reject(e);
642-
process.nextTick(function(){
643-
throwdomainError;
644-
});
645-
});
646-
}
647-
);
648-
649624
asyncTest('nextTick is immediately scheduled when called inside an event'+
650625
' handler',function(done){
651626
clean();

0 commit comments

Comments
 (0)