|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"use strict"; |
|
module.exports = function() { |
|
var ASSERT = require("./assert.js"); |
|
var inherits = require("./util.js").inherits; |
|
var defineProperty = require("./es5.js").defineProperty; |
|
|
|
var rignore = new RegExp( |
|
"\\b(?:[\\w.]*Promise(?:Array|Spawn)?\\$_\\w+|" + |
|
"tryCatch(?:1|2|Apply)|new \\w*PromiseArray|" + |
|
"\\w*PromiseArray\\.\\w*PromiseArray|" + |
|
"setTimeout|CatchFilter\\$_\\w+|makeNodePromisified|processImmediate|" + |
|
"process._tickCallback|nextTick|Async\\$\\w+)\\b" |
|
); |
|
|
|
var rtraceline = null; |
|
var formatStack = null; |
|
var areNamesMangled = false; |
|
|
|
function formatNonError(obj) { |
|
var str; |
|
if (typeof obj === "function") { |
|
str = "[function " + |
|
(obj.name || "anonymous") + |
|
"]"; |
|
} |
|
else { |
|
str = obj.toString(); |
|
var ruselessToString = /\[object [a-zA-Z0-9$_]+\]/; |
|
if (ruselessToString.test(str)) { |
|
try { |
|
var newStr = JSON.stringify(obj); |
|
str = newStr; |
|
} |
|
catch(e) { |
|
|
|
} |
|
} |
|
if (str.length === 0) { |
|
str = "(empty array)"; |
|
} |
|
} |
|
return ("(<" + snip(str) + ">, no stack trace)"); |
|
} |
|
|
|
function snip(str) { |
|
var maxChars = 41; |
|
if (str.length < maxChars) { |
|
return str; |
|
} |
|
return str.substr(0, maxChars - 3) + "..."; |
|
} |
|
|
|
function CapturedTrace(ignoreUntil, isTopLevel) { |
|
if (!areNamesMangled) { |
|
} |
|
this.captureStackTrace(ignoreUntil, isTopLevel); |
|
|
|
} |
|
inherits(CapturedTrace, Error); |
|
|
|
CapturedTrace.prototype.captureStackTrace = |
|
function CapturedTrace$captureStackTrace(ignoreUntil, isTopLevel) { |
|
captureStackTrace(this, ignoreUntil, isTopLevel); |
|
}; |
|
|
|
CapturedTrace.possiblyUnhandledRejection = |
|
function CapturedTrace$PossiblyUnhandledRejection(reason) { |
|
if (typeof console === "object") { |
|
var message; |
|
if (typeof reason === "object" || typeof reason === "function") { |
|
var stack = reason.stack; |
|
message = "Possibly unhandled " + formatStack(stack, reason); |
|
} |
|
else { |
|
message = "Possibly unhandled " + String(reason); |
|
} |
|
if (typeof console.error === "function" || |
|
typeof console.error === "object") { |
|
console.error(message); |
|
} |
|
else if (typeof console.log === "function" || |
|
typeof console.error === "object") { |
|
console.log(message); |
|
} |
|
} |
|
}; |
|
|
|
areNamesMangled = CapturedTrace.prototype.captureStackTrace.name !== |
|
"CapturedTrace$captureStackTrace"; |
|
|
|
CapturedTrace.combine = function CapturedTrace$Combine(current, prev) { |
|
var curLast = current.length - 1; |
|
for (var i = prev.length - 1; i >= 0; --i) { |
|
var line = prev[i]; |
|
if (current[curLast] === line) { |
|
current.pop(); |
|
curLast--; |
|
} |
|
else { |
|
break; |
|
} |
|
} |
|
|
|
current.push("From previous event:"); |
|
var lines = current.concat(prev); |
|
|
|
var ret = []; |
|
|
|
|
|
for (var i = 0, len = lines.length; i < len; ++i) { |
|
|
|
if ((rignore.test(lines[i]) || |
|
(i > 0 && !rtraceline.test(lines[i])) && |
|
lines[i] !== "From previous event:") |
|
) { |
|
continue; |
|
} |
|
ret.push(lines[i]); |
|
} |
|
return ret; |
|
}; |
|
|
|
CapturedTrace.isSupported = function CapturedTrace$IsSupported() { |
|
return typeof captureStackTrace === "function"; |
|
}; |
|
|
|
var captureStackTrace = (function stackDetection() { |
|
if (typeof Error.stackTraceLimit === "number" && |
|
typeof Error.captureStackTrace === "function") { |
|
rtraceline = /^\s*at\s*/; |
|
formatStack = function(stack, error) { |
|
if (typeof stack === "string") return stack; |
|
|
|
if (error.name !== void 0 && |
|
error.message !== void 0) { |
|
return error.name + ". " + error.message; |
|
} |
|
return formatNonError(error); |
|
|
|
|
|
}; |
|
var captureStackTrace = Error.captureStackTrace; |
|
return function CapturedTrace$_captureStackTrace( |
|
receiver, ignoreUntil) { |
|
captureStackTrace(receiver, ignoreUntil); |
|
}; |
|
} |
|
var err = new Error(); |
|
|
|
if (!areNamesMangled && typeof err.stack === "string" && |
|
typeof "".startsWith === "function" && |
|
(err.stack.startsWith("stackDetection@")) && |
|
stackDetection.name === "stackDetection") { |
|
|
|
defineProperty(Error, "stackTraceLimit", { |
|
writable: true, |
|
enumerable: false, |
|
configurable: false, |
|
value: 25 |
|
}); |
|
rtraceline = /@/; |
|
var rline = /[@\n]/; |
|
|
|
formatStack = function(stack, error) { |
|
if (typeof stack === "string") { |
|
return (error.name + ". " + error.message + "\n" + stack); |
|
} |
|
|
|
if (error.name !== void 0 && |
|
error.message !== void 0) { |
|
return error.name + ". " + error.message; |
|
} |
|
return formatNonError(error); |
|
}; |
|
|
|
return function captureStackTrace(o, fn) { |
|
var name = fn.name; |
|
var stack = new Error().stack; |
|
var split = stack.split(rline); |
|
var i, len = split.length; |
|
for (i = 0; i < len; i += 2) { |
|
if (split[i] === name) { |
|
break; |
|
} |
|
} |
|
split = split.slice(i + 2); |
|
len = split.length - 2; |
|
var ret = ""; |
|
for (i = 0; i < len; i += 2) { |
|
ret += split[i]; |
|
ret += "@"; |
|
ret += split[i + 1]; |
|
ret += "\n"; |
|
} |
|
o.stack = ret; |
|
}; |
|
} |
|
else { |
|
formatStack = function(stack, error) { |
|
if (typeof stack === "string") return stack; |
|
|
|
if ((typeof error === "object" || |
|
typeof error === "function") && |
|
error.name !== void 0 && |
|
error.message !== void 0) { |
|
return error.name + ". " + error.message; |
|
} |
|
return formatNonError(error); |
|
}; |
|
|
|
return null; |
|
} |
|
})(); |
|
|
|
return CapturedTrace; |
|
}; |
|
|