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.
136 lines
3.3 KiB
136 lines
3.3 KiB
exports.get = function(belowFn) { |
|
var oldLimit = Error.stackTraceLimit; |
|
Error.stackTraceLimit = Infinity; |
|
|
|
var dummyObject = {}; |
|
|
|
var v8Handler = Error.prepareStackTrace; |
|
Error.prepareStackTrace = function(dummyObject, v8StackTrace) { |
|
return v8StackTrace; |
|
}; |
|
Error.captureStackTrace(dummyObject, belowFn || exports.get); |
|
|
|
var v8StackTrace = dummyObject.stack; |
|
Error.prepareStackTrace = v8Handler; |
|
Error.stackTraceLimit = oldLimit; |
|
|
|
return v8StackTrace; |
|
}; |
|
|
|
exports.parse = function(err) { |
|
if (!err.stack) { |
|
return []; |
|
} |
|
|
|
var self = this; |
|
var lines = err.stack.split('\n').slice(1); |
|
|
|
return lines |
|
.map(function(line) { |
|
if (line.match(/^\s*[-]{4,}$/)) { |
|
return self._createParsedCallSite({ |
|
fileName: line, |
|
lineNumber: null, |
|
functionName: null, |
|
typeName: null, |
|
methodName: null, |
|
columnNumber: null, |
|
'native': null, |
|
}); |
|
} |
|
|
|
var lineMatch = line.match(/at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/); |
|
if (!lineMatch) { |
|
return; |
|
} |
|
|
|
var object = null; |
|
var method = null; |
|
var functionName = null; |
|
var typeName = null; |
|
var methodName = null; |
|
var isNative = (lineMatch[5] === 'native'); |
|
|
|
if (lineMatch[1]) { |
|
functionName = lineMatch[1]; |
|
var methodStart = functionName.lastIndexOf('.'); |
|
if (functionName[methodStart-1] == '.') |
|
methodStart--; |
|
if (methodStart > 0) { |
|
object = functionName.substr(0, methodStart); |
|
method = functionName.substr(methodStart + 1); |
|
var objectEnd = object.indexOf('.Module'); |
|
if (objectEnd > 0) { |
|
functionName = functionName.substr(objectEnd + 1); |
|
object = object.substr(0, objectEnd); |
|
} |
|
} |
|
typeName = null; |
|
} |
|
|
|
if (method) { |
|
typeName = object; |
|
methodName = method; |
|
} |
|
|
|
if (method === '<anonymous>') { |
|
methodName = null; |
|
functionName = null; |
|
} |
|
|
|
var properties = { |
|
fileName: lineMatch[2] || null, |
|
lineNumber: parseInt(lineMatch[3], 10) || null, |
|
functionName: functionName, |
|
typeName: typeName, |
|
methodName: methodName, |
|
columnNumber: parseInt(lineMatch[4], 10) || null, |
|
'native': isNative, |
|
}; |
|
|
|
return self._createParsedCallSite(properties); |
|
}) |
|
.filter(function(callSite) { |
|
return !!callSite; |
|
}); |
|
}; |
|
|
|
function CallSite(properties) { |
|
for (var property in properties) { |
|
this[property] = properties[property]; |
|
} |
|
} |
|
|
|
var strProperties = [ |
|
'this', |
|
'typeName', |
|
'functionName', |
|
'methodName', |
|
'fileName', |
|
'lineNumber', |
|
'columnNumber', |
|
'function', |
|
'evalOrigin' |
|
]; |
|
var boolProperties = [ |
|
'topLevel', |
|
'eval', |
|
'native', |
|
'constructor' |
|
]; |
|
strProperties.forEach(function (property) { |
|
CallSite.prototype[property] = null; |
|
CallSite.prototype['get' + property[0].toUpperCase() + property.substr(1)] = function () { |
|
return this[property]; |
|
} |
|
}); |
|
boolProperties.forEach(function (property) { |
|
CallSite.prototype[property] = false; |
|
CallSite.prototype['is' + property[0].toUpperCase() + property.substr(1)] = function () { |
|
return this[property]; |
|
} |
|
}); |
|
|
|
exports._createParsedCallSite = function(properties) { |
|
return new CallSite(properties); |
|
};
|
|
|