Comparing version 1.2.1 to 1.3.0
<!-- vim:ts=4:sts=4:sw=4:et:tw=70 --> | ||
## 1.3.0 | ||
- Add tracking for unhandled and handled rejections in Node.js (@benjamingr). | ||
## 1.2.1 | ||
@@ -4,0 +8,0 @@ |
{ | ||
"name": "q", | ||
"version": "1.2.1", | ||
"version": "1.3.0", | ||
"description": "A library for promises (CommonJS/Promises/A,B,D)", | ||
@@ -5,0 +5,0 @@ "homepage": "https://github.com/kriskowal/q", |
109
q.js
@@ -94,11 +94,14 @@ // vim:ts=4:sts=4:sw=4: | ||
var isNodeJS = false; | ||
// queue for late tasks, used by unhandled rejection tracking | ||
var laterQueue = []; | ||
function flush() { | ||
/* jshint loopfunc: true */ | ||
var task, domain; | ||
while (head.next) { | ||
head = head.next; | ||
var task = head.task; | ||
task = head.task; | ||
head.task = void 0; | ||
var domain = head.domain; | ||
domain = head.domain; | ||
@@ -109,39 +112,46 @@ if (domain) { | ||
} | ||
runSingle(task, domain); | ||
try { | ||
task(); | ||
} | ||
while (laterQueue.length) { | ||
task = laterQueue.pop(); | ||
runSingle(task); | ||
} | ||
flushing = false; | ||
} | ||
// runs a single function in the async queue | ||
function runSingle(task, domain) { | ||
try { | ||
task(); | ||
} catch (e) { | ||
if (isNodeJS) { | ||
// In node, uncaught exceptions are considered fatal errors. | ||
// Re-throw them synchronously to interrupt flushing! | ||
} catch (e) { | ||
if (isNodeJS) { | ||
// In node, uncaught exceptions are considered fatal errors. | ||
// Re-throw them synchronously to interrupt flushing! | ||
// Ensure continuation if the uncaught exception is suppressed | ||
// listening "uncaughtException" events (as domains does). | ||
// Continue in next event to avoid tick recursion. | ||
if (domain) { | ||
domain.exit(); | ||
} | ||
setTimeout(flush, 0); | ||
if (domain) { | ||
domain.enter(); | ||
} | ||
// Ensure continuation if the uncaught exception is suppressed | ||
// listening "uncaughtException" events (as domains does). | ||
// Continue in next event to avoid tick recursion. | ||
if (domain) { | ||
domain.exit(); | ||
} | ||
setTimeout(flush, 0); | ||
if (domain) { | ||
domain.enter(); | ||
} | ||
throw e; | ||
} else { | ||
// In browsers, uncaught exceptions are not fatal. | ||
// Re-throw them asynchronously to avoid slow-downs. | ||
setTimeout(function () { | ||
throw e; | ||
} else { | ||
// In browsers, uncaught exceptions are not fatal. | ||
// Re-throw them asynchronously to avoid slow-downs. | ||
setTimeout(function() { | ||
throw e; | ||
}, 0); | ||
} | ||
}, 0); | ||
} | ||
} | ||
if (domain) { | ||
domain.exit(); | ||
} | ||
if (domain) { | ||
domain.exit(); | ||
} | ||
flushing = false; | ||
} | ||
@@ -215,3 +225,12 @@ | ||
} | ||
// runs a task after all other tasks have been run | ||
// this is useful for unhandled rejection tracking that needs to happen | ||
// after all `then`d tasks have been run. | ||
nextTick.runAfter = function (task) { | ||
laterQueue.push(task); | ||
if (!flushing) { | ||
flushing = true; | ||
requestTick(); | ||
} | ||
}; | ||
return nextTick; | ||
@@ -710,5 +729,5 @@ })(); | ||
function race(answerPs) { | ||
return promise(function(resolve, reject) { | ||
return promise(function (resolve, reject) { | ||
// Switch to this once we can assume at least ES5 | ||
// answerPs.forEach(function(answerP) { | ||
// answerPs.forEach(function (answerP) { | ||
// Q(answerP).then(resolve, reject); | ||
@@ -1011,2 +1030,3 @@ // }); | ||
var unhandledRejections = []; | ||
var reportedUnhandledRejections = []; | ||
var trackUnhandledRejections = true; | ||
@@ -1027,2 +1047,10 @@ | ||
} | ||
if (typeof process === "object" && typeof process.emit === "function") { | ||
Q.nextTick.runAfter(function () { | ||
if (array_indexOf(unhandledRejections, promise) !== -1) { | ||
process.emit("unhandledRejection", reason, promise); | ||
reportedUnhandledRejections.push(promise); | ||
} | ||
}); | ||
} | ||
@@ -1044,2 +1072,11 @@ unhandledRejections.push(promise); | ||
if (at !== -1) { | ||
if (typeof process === "object" && typeof process.emit === "function") { | ||
Q.nextTick.runAfter(function () { | ||
var atReport = array_indexOf(reportedUnhandledRejections, promise); | ||
if (atReport !== -1) { | ||
process.emit("rejectionHandled", unhandledReasons[at], promise); | ||
reportedUnhandledRejections.splice(atReport, 1); | ||
} | ||
}); | ||
} | ||
unhandledRejections.splice(at, 1); | ||
@@ -1572,3 +1609,3 @@ unhandledReasons.splice(at, 1); | ||
var pendingCount = 0; | ||
array_reduce(promises, function(prev, current, index) { | ||
array_reduce(promises, function (prev, current, index) { | ||
var promise = promises[index]; | ||
@@ -1602,3 +1639,3 @@ | ||
Promise.prototype.any = function() { | ||
Promise.prototype.any = function () { | ||
return any(this); | ||
@@ -1605,0 +1642,0 @@ }; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
121097
1840