Skip to content

Commit

Permalink
add captureRejection option
Browse files Browse the repository at this point in the history
  • Loading branch information
goto-bus-stop committed Feb 28, 2021
1 parent e9fb908 commit 09b01f1
Show file tree
Hide file tree
Showing 4 changed files with 391 additions and 55 deletions.
67 changes: 64 additions & 3 deletions events.js
Expand Up @@ -129,6 +129,50 @@ EventEmitter.init = function init(opts) {
}
};

var ProcessNextTick = typeof queueMicrotask === 'function'
? queueMicrotask
: typeof setImmediate === 'function'
? setImmediate
: setTimeout;

function addCatch(that, promise, type, args) {
if (!that[kCapture]) {
return;
}

// Handle Promises/A+ spec, then could be a getter
// that throws on second use.
try {
var then = promise.then;
if (typeof then === 'function') {
then.call(promise, undefined, function(err) {
ProcessNextTick(function () {
emitUnhandledRejectionOrErr(that, err, type, args);
});
});
}
} catch (err) {
that.emit('error', err);
}
}

function emitUnhandledRejectionOrErr(ee, err, type, args) {
if (typeof ee[kRejection] === 'function') {
ee[kRejection].apply(ee, [err, type].concat(args));
} else {
// We have to disable the capture rejections mechanism, otherwise
// we might end up in an infinite loop.
var prev = ee[kCapture];

try {
ee[kCapture] = false;
ee.emit('error', err);
} finally {
ee[kCapture] = prev;
}
}
}

// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
Expand Down Expand Up @@ -182,12 +226,29 @@ EventEmitter.prototype.emit = function emit(type) {
return false;

if (typeof handler === 'function') {
ReflectApply(handler, this, args);
var result = ReflectApply(handler, this, args);

// We check if result is undefined first because that
// is the most common case so we do not pay any perf
// penalty
if (result !== undefined && result !== null) {
addCatch(this, result, type, args);
}
} else {
var len = handler.length;
var listeners = arrayClone(handler, len);
for (var i = 0; i < len; ++i)
ReflectApply(listeners[i], this, args);
for (var i = 0; i < len; ++i) {
var result = ReflectApply(listeners[i], this, args);

// We check if result is undefined first because that
// is the most common case so we do not pay any perf
// penalty.
// This code is duplicated because extracting it away
// would make it non-inlineable.
if (result !== undefined && result !== null) {
addCatch(this, result, type, args);
}
}
}

return true;
Expand Down

0 comments on commit 09b01f1

Please sign in to comment.