Skip to content

Commit b516d5b

Browse files
committed
add triggering unhandled promise rejection events, fixes #205
1 parent dce21a9 commit b516d5b

File tree

5 files changed

+53
-10
lines changed

5 files changed

+53
-10
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- `.forEach` method to iterable DOM collections ([#329](https://github.com/zloirock/core-js/issues/329))
55
- `Symbol#description` ([stage 1 proposal](https://tc39.github.io/proposal-Symbol-description/))
66
- `String#replaceAll` ([stage 1 proposal](https://github.com/psmarshall/string-replace-all-proposal))
7+
- Triggering unhandled `Promise` rejection events (instead of only global handlers) [#205](https://github.com/zloirock/core-js/issues/205)
78
- Removed obsolete features:
89
- `Error.isError` (withdrawn)
910
- `System.global` (replaced by `global`)

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,9 @@ setTimeout(() => promise.catch(() => {}), 1e3);
801801
```
802802
In a browser on rejection, by default, you will see notify in the console, or you can add a custom handler and a handler on handling unhandled, [*example*](http://goo.gl/Wozskl):
803803
```js
804+
window.addEventListener('unhandledrejection', e => console.log('unhandled', e.reason, e.promise));
805+
window.addEventListener('rejectionhandled', e => console.log('handled', e.reason, e.promise));
806+
// or
804807
window.onunhandledrejection = e => console.log('unhandled', e.reason, e.promise);
805808
window.onrejectionhandled = e => console.log('handled', e.reason, e.promise);
806809

modules/es.promise.js

+19-8
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,15 @@ var hostReportErrors = require('./_host-report-errors');
1818
var PROMISE = 'Promise';
1919
var TypeError = global.TypeError;
2020
var process = global.process;
21+
var document = global.document;
2122
var $Promise = global[PROMISE];
2223
var isNode = classof(process) == 'process';
2324
var empty = function () { /* empty */ };
2425
var Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper;
2526
var newPromiseCapability = newGenericPromiseCapability = newPromiseCapabilityModule.f;
27+
var DISPATCH_EVENT = !!(document && document.createEvent && global.dispatchEvent);
28+
var UNHANDLED_REJECTION = 'unhandledrejection';
29+
var REJECTION_HANDLED = 'rejectionhandled';
2630

2731
var USE_NATIVE = !!function () {
2832
try {
@@ -87,18 +91,28 @@ var notify = function (promise, isReject) {
8791
if (isReject && !promise._h) onUnhandled(promise);
8892
});
8993
};
94+
var dispatchEvent = function (name, promise, reason) {
95+
var event, handler;
96+
if (DISPATCH_EVENT) {
97+
event = document.createEvent('Event');
98+
event.promise = promise;
99+
event.reason = reason;
100+
event.initEvent(name, false, true);
101+
global.dispatchEvent(event);
102+
} else event = { promise: promise, reason: reason };
103+
if (handler = global['on' + name]) handler(event);
104+
else if (name === UNHANDLED_REJECTION) hostReportErrors('Unhandled promise rejection', reason);
105+
};
90106
var onUnhandled = function (promise) {
91107
task.call(global, function () {
92108
var value = promise._v;
93109
var unhandled = isUnhandled(promise);
94-
var result, handler;
110+
var result;
95111
if (unhandled) {
96112
result = perform(function () {
97113
if (isNode) {
98114
process.emit('unhandledRejection', value, promise);
99-
} else if (handler = global.onunhandledrejection) {
100-
handler({ promise: promise, reason: value });
101-
} else hostReportErrors('Unhandled promise rejection', value);
115+
} else dispatchEvent(UNHANDLED_REJECTION, promise, value);
102116
});
103117
// Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should
104118
promise._h = isNode || isUnhandled(promise) ? 2 : 1;
@@ -111,12 +125,9 @@ var isUnhandled = function (promise) {
111125
};
112126
var onHandleUnhandled = function (promise) {
113127
task.call(global, function () {
114-
var handler;
115128
if (isNode) {
116129
process.emit('rejectionHandled', promise);
117-
} else if (handler = global.onrejectionhandled) {
118-
handler({ promise: promise, reason: promise._v });
119-
}
130+
} else dispatchEvent(REJECTION_HANDLED, promise, promise._v);
120131
});
121132
};
122133
var $reject = function (value) {

tests/library/es.promise.js

+15-1
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,21 @@ QUnit.test('Unhandled rejection tracking', assert => {
390390
process.on('unhandledRejection', onunhandledrejection);
391391
process.on('rejectionHandled', onrejectionhandled);
392392
} else {
393-
assert.expect(4);
393+
if (GLOBAL.addEventListener) {
394+
assert.expect(8);
395+
function onunhandledrejection(it) {
396+
assert.same(it.promise, $promise, 'addEventListener(unhandledrejection), promise');
397+
assert.same(it.reason, 42, 'addEventListener(unhandledrejection), reason');
398+
GLOBAL.removeEventListener('unhandledrejection', onunhandledrejection);
399+
}
400+
GLOBAL.addEventListener('rejectionhandled', onunhandledrejection);
401+
function onrejectionhandled(it) {
402+
assert.same(it.promise, $promise, 'addEventListener(rejectionhandled), promise');
403+
assert.same(it.reason, 42, 'addEventListener(rejectionhandled), reason');
404+
GLOBAL.removeEventListener('rejectionhandled', onrejectionhandled);
405+
}
406+
GLOBAL.addEventListener('rejectionhandled', onrejectionhandled);
407+
} else assert.expect(4);
394408
GLOBAL.onunhandledrejection = function (it) {
395409
assert.same(it.promise, $promise, 'onunhandledrejection, promise');
396410
assert.same(it.reason, 42, 'onunhandledrejection, reason');

tests/tests/es.promise.js

+15-1
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,21 @@ QUnit.test('Unhandled rejection tracking', assert => {
414414
process.on('unhandledRejection', onunhandledrejection);
415415
process.on('rejectionHandled', onrejectionhandled);
416416
} else {
417-
assert.expect(4);
417+
if (GLOBAL.addEventListener) {
418+
assert.expect(8);
419+
function onunhandledrejection(it) {
420+
assert.same(it.promise, $promise, 'addEventListener(unhandledrejection), promise');
421+
assert.same(it.reason, 42, 'addEventListener(unhandledrejection), reason');
422+
GLOBAL.removeEventListener('unhandledrejection', onunhandledrejection);
423+
}
424+
GLOBAL.addEventListener('rejectionhandled', onunhandledrejection);
425+
function onrejectionhandled(it) {
426+
assert.same(it.promise, $promise, 'addEventListener(rejectionhandled), promise');
427+
assert.same(it.reason, 42, 'addEventListener(rejectionhandled), reason');
428+
GLOBAL.removeEventListener('rejectionhandled', onrejectionhandled);
429+
}
430+
GLOBAL.addEventListener('rejectionhandled', onrejectionhandled);
431+
} else assert.expect(4);
418432
GLOBAL.onunhandledrejection = function (it) {
419433
assert.same(it.promise, $promise, 'onunhandledrejection, promise');
420434
assert.same(it.reason, 42, 'onunhandledrejection, reason');

0 commit comments

Comments
 (0)