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]) { var methodMatch = lineMatch[1].match(/([^\.]+)(?:\.(.+))?/); object = methodMatch[1]; method = methodMatch[2]; functionName = lineMatch[1]; typeName = 'Object'; } if (method) { typeName = object; methodName = method; } if (method === '') { methodName = null; functionName = ''; } 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; }); }; exports._createParsedCallSite = function(properties) { var methods = {}; for (var property in properties) { var prefix = 'get'; if (property === 'native') { prefix = 'is'; } var method = prefix + property.substr(0, 1).toUpperCase() + property.substr(1); (function(property) { methods[method] = function() { return properties[property]; } })(property); } var callSite = Object.create(methods); for (var property in properties) { callSite[property] = properties[property]; } return callSite; };