cujojs / when

A solid, fast Promises/A+ and when() implementation, plus other async goodies.
Other
3.44k stars 396 forks source link

Report unhandled without using promise.done #305

Closed briancavalier closed 10 years ago

briancavalier commented 10 years ago

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 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)

  1. Promise.onUnhandledRejection - called immediately when a rejection is created,
  2. Promise.onUnhandledRejectionHandled - called immediately when a rejection is "handled" (ie someone calls then on it, or "observes" it in any other way), and
  3. 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.