cujojs / when

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

Global rejection events completely broken in a bundled environment (eg. Webpack) #490

Open joepie91 opened 8 years ago

joepie91 commented 8 years ago

The code for initEmitRejection seems to be checking for a Node environment incorrectly:

if(typeof process !== 'undefined' && process !== null
    && typeof process.emit === 'function') {

... leading to WhenJS incorrectly concluding that bundled code is running in Node, therefore emitting its events through process.emit (which is a noop) and completely skipping window.dispatchEvent, essentially breaking the global rejection events entirely.

The following is the set of checks I'm using in my code, which appears to be more robust, and which I've found to be working in the current version of Webpack:

let isWebWorker = (typeof WorkerGlobalScope !== "undefined");
let isNode = (typeof process !== "undefined" && process.browser !== true);
let isBrowser = (!isNode && !isWebWorker && typeof document !== "undefined");

Given that the referenced shim explicitly sets process.browser to true, that seems like a better way to identify (bundled) browser environments. I'm not sure whether this property is also present in older versions.


As an aside, the code in initEmitRejection also says the following:

// Returning falsy here means to call the default
// onPotentiallyUnhandledRejection API.  This is safe even in
// browserify since process.emit always returns falsy in browserify:
// https://github.com/defunctzombie/node-process/blob/master/browser.js#L40-L46

... however, looking at the current version of that code, this seems to not be true - process.emit is a noop, which thus returns undefined, and I'm not certain that evaluates as 'falsey' from an event handling perspective.