'use strict'; var Promise = require('./core'); var DEFAULT_WHITELIST = [ ReferenceError, TypeError, RangeError ]; var enabled = false; exports.disable = disable; function disable() { enabled = false; Promise._l = null; Promise._m = null; } exports.enable = enable; function enable(options) { options = options || {}; if (enabled) disable(); enabled = true; var id = 0; var displayId = 0; var rejections = {}; Promise._l = function (promise) { if ( promise._i === 2 && // IS REJECTED rejections[promise._o] ) { if (rejections[promise._o].logged) { onHandled(promise._o); } else { clearTimeout(rejections[promise._o].timeout); } delete rejections[promise._o]; } }; Promise._m = function (promise, err) { if (promise._h === 0) { // not yet handled promise._o = id++; rejections[promise._o] = { displayId: null, error: err, timeout: setTimeout( onUnhandled.bind(null, promise._o), // For reference errors and type errors, this almost always // means the programmer made a mistake, so log them after just // 100ms // otherwise, wait 2 seconds to see if they get handled matchWhitelist(err, DEFAULT_WHITELIST) ? 100 : 2000 ), logged: false }; } }; function onUnhandled(id) { if ( options.allRejections || matchWhitelist( rejections[id].error, options.whitelist || DEFAULT_WHITELIST ) ) { rejections[id].displayId = displayId++; if (options.onUnhandled) { rejections[id].logged = true; options.onUnhandled( rejections[id].displayId, rejections[id].error ); } else { rejections[id].logged = true; logError( rejections[id].displayId, rejections[id].error ); } } } function onHandled(id) { if (rejections[id].logged) { if (options.onHandled) { options.onHandled(rejections[id].displayId, rejections[id].error); } else if (!rejections[id].onUnhandled) { console.warn( 'Promise Rejection Handled (id: ' + rejections[id].displayId + '):' ); console.warn( ' This means you can ignore any previous messages of the form "Possible Unhandled Promise Rejection" with id ' + rejections[id].displayId + '.' ); } } } } function logError(id, error) { console.warn('Possible Unhandled Promise Rejection (id: ' + id + '):'); var errStr = (error && (error.stack || error)) + ''; errStr.split('\n').forEach(function (line) { console.warn(' ' + line); }); } function matchWhitelist(error, list) { return list.some(function (cls) { return error instanceof cls; }); }