This makes unhandled rejections loud by default (no monitor required, and without using promise.done). The perf impact is nearly zero because it does not track the extra info needed to reconstruct long stack traces. You get a loud console.error message (not a fatal next tick throw) with a "normal" stack trace.
How it works
When a rejection is created, it immediately puts it into a list. Then, it sets a timer, if not already set/pending, to run through the rejections list and report all rejections which were not marked as "handled" (literally rejection.handled == true) between the time they were created and when the timer fired.
Yes, this relies on timing, but I'm pretty sure there's no better way without garbage collector hooks. The main worry is, of course, false positives. There are 2 ways to deal with that: increase the interval, and allow users to configure/override some parts of the algorithm. I opted for the latter.
Configurability
There are 3 public hooks (names subject to tweaking, of course!). The behavior described above is implemented using these 3 hooks in a new decorator: lib/decorator/unhandledRejection. That means, the es6-shim does not get this new behavior, but also means it doesn't take the added size hit (which is about 200 bytes min+gzip)
Promise.onUnhandledRejection - called immediately when a rejection is created,
Promise.onUnhandledRejectionHandled - called immediately when a rejection is "handled" (ie someone calls then on it, or "observes" it in any other way), and
Promise.onFatalRejection - called when an error (rejection or exception) pops out the other side of promise.done.
wtf git rebase
Something funky happened while rebasing this on dev. I'll have to look into it, but since it's only for discussion right now, you can ignore the first 3 commits.
Loud by default
This makes unhandled rejections loud by default (no monitor required, and without using
promise.done
). The perf impact is nearly zero because it does not track the extra info needed to reconstruct long stack traces. You get a loudconsole.error
message (not a fatal next tick throw) with a "normal" stack trace.How it works
When a rejection is created, it immediately puts it into a list. Then, it sets a timer, if not already set/pending, to run through the rejections list and report all rejections which were not marked as "handled" (literally
rejection.handled == true
) between the time they were created and when the timer fired.Yes, this relies on timing, but I'm pretty sure there's no better way without garbage collector hooks. The main worry is, of course, false positives. There are 2 ways to deal with that: increase the interval, and allow users to configure/override some parts of the algorithm. I opted for the latter.
Configurability
There are 3 public hooks (names subject to tweaking, of course!). The behavior described above is implemented using these 3 hooks in a new decorator:
lib/decorator/unhandledRejection
. That means, the es6-shim does not get this new behavior, but also means it doesn't take the added size hit (which is about 200 bytes min+gzip)Promise.onUnhandledRejection
- called immediately when a rejection is created,Promise.onUnhandledRejectionHandled
- called immediately when a rejection is "handled" (ie someone callsthen
on it, or "observes" it in any other way), andPromise.onFatalRejection
- called when an error (rejection or exception) pops out the other side ofpromise.done
.wtf git rebase
Something funky happened while rebasing this on dev. I'll have to look into it, but since it's only for discussion right now, you can ignore the first 3 commits.