You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
113 lines
2.8 KiB
113 lines
2.8 KiB
'use strict'; |
|
|
|
var Promise = require('./core'); |
|
|
|
var DEFAULT_WHITELIST = [ |
|
ReferenceError, |
|
TypeError, |
|
RangeError |
|
]; |
|
|
|
var enabled = false; |
|
exports.disable = disable; |
|
function disable() { |
|
enabled = false; |
|
Promise._37 = null; |
|
Promise._87 = null; |
|
} |
|
|
|
exports.enable = enable; |
|
function enable(options) { |
|
options = options || {}; |
|
if (enabled) disable(); |
|
enabled = true; |
|
var id = 0; |
|
var displayId = 0; |
|
var rejections = {}; |
|
Promise._37 = function (promise) { |
|
if ( |
|
promise._65 === 2 && // IS REJECTED |
|
rejections[promise._51] |
|
) { |
|
if (rejections[promise._51].logged) { |
|
onHandled(promise._51); |
|
} else { |
|
clearTimeout(rejections[promise._51].timeout); |
|
} |
|
delete rejections[promise._51]; |
|
} |
|
}; |
|
Promise._87 = function (promise, err) { |
|
if (promise._40 === 0) { // not yet handled |
|
promise._51 = id++; |
|
rejections[promise._51] = { |
|
displayId: null, |
|
error: err, |
|
timeout: setTimeout( |
|
onUnhandled.bind(null, promise._51), |
|
// 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; |
|
}); |
|
} |