mirror of https://gitee.com/bigwinds/arangodb
136 lines
5.8 KiB
JavaScript
136 lines
5.8 KiB
JavaScript
(function (root, factory) {
|
|
'use strict';
|
|
// Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, Rhino, and browsers.
|
|
if (typeof define === 'function' && define.amd) {
|
|
define('error-stack-parser', ['stackframe'], factory);
|
|
} else if (typeof exports === 'object') {
|
|
module.exports = factory(require('stackframe'));
|
|
} else {
|
|
root.ErrorStackParser = factory(root.StackFrame);
|
|
}
|
|
}(this, function ErrorStackParser(StackFrame) {
|
|
'use strict';
|
|
|
|
var FIREFOX_SAFARI_STACK_REGEXP = /\S+\:\d+/;
|
|
var CHROME_IE_STACK_REGEXP = /\s+at /;
|
|
|
|
return {
|
|
/**
|
|
* Given an Error object, extract the most information from it.
|
|
* @param error {Error}
|
|
* @return Array[StackFrame]
|
|
*/
|
|
parse: function ErrorStackParser$$parse(error) {
|
|
if (typeof error.stacktrace !== 'undefined' || typeof error['opera#sourceloc'] !== 'undefined') {
|
|
return this.parseOpera(error);
|
|
} else if (error.stack && error.stack.match(CHROME_IE_STACK_REGEXP)) {
|
|
return this.parseV8OrIE(error);
|
|
} else if (error.stack && error.stack.match(FIREFOX_SAFARI_STACK_REGEXP)) {
|
|
return this.parseFFOrSafari(error);
|
|
} else {
|
|
throw new Error('Cannot parse given Error object');
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Separate line and column numbers from a URL-like string.
|
|
* @param urlLike String
|
|
* @return Array[String]
|
|
*/
|
|
extractLocation: function ErrorStackParser$$extractLocation(urlLike) {
|
|
var locationParts = urlLike.split(':');
|
|
var lastNumber = locationParts.pop();
|
|
var possibleNumber = locationParts[locationParts.length - 1];
|
|
if (!isNaN(parseFloat(possibleNumber)) && isFinite(possibleNumber)) {
|
|
var lineNumber = locationParts.pop();
|
|
return [locationParts.join(':'), lineNumber, lastNumber];
|
|
} else {
|
|
return [locationParts.join(':'), lastNumber, undefined];
|
|
}
|
|
},
|
|
|
|
parseV8OrIE: function ErrorStackParser$$parseV8OrIE(error) {
|
|
return error.stack.split('\n').slice(1).map(function (line) {
|
|
var tokens = line.replace(/^\s+/, '').split(/\s+/).slice(1);
|
|
var locationParts = this.extractLocation(tokens.pop().replace(/[\(\)\s]/g, ''));
|
|
var functionName = (!tokens[0] || tokens[0] === 'Anonymous') ? undefined : tokens[0];
|
|
return new StackFrame(functionName, undefined, locationParts[0], locationParts[1], locationParts[2]);
|
|
}, this);
|
|
},
|
|
|
|
parseFFOrSafari: function ErrorStackParser$$parseFFOrSafari(error) {
|
|
return error.stack.split('\n').filter(function (line) {
|
|
return !!line.match(FIREFOX_SAFARI_STACK_REGEXP);
|
|
}, this).map(function (line) {
|
|
var tokens = line.split('@');
|
|
var locationParts = this.extractLocation(tokens.pop());
|
|
var functionName = tokens.shift() || undefined;
|
|
return new StackFrame(functionName, undefined, locationParts[0], locationParts[1], locationParts[2]);
|
|
}, this);
|
|
},
|
|
|
|
parseOpera: function ErrorStackParser$$parseOpera(e) {
|
|
if (!e.stacktrace || (e.message.indexOf('\n') > -1 &&
|
|
e.message.split('\n').length > e.stacktrace.split('\n').length)) {
|
|
return this.parseOpera9(e);
|
|
} else if (!e.stack) {
|
|
return this.parseOpera10(e);
|
|
} else {
|
|
return this.parseOpera11(e);
|
|
}
|
|
},
|
|
|
|
parseOpera9: function ErrorStackParser$$parseOpera9(e) {
|
|
var lineRE = /Line (\d+).*script (?:in )?(\S+)/i;
|
|
var lines = e.message.split('\n');
|
|
var result = [];
|
|
|
|
for (var i = 2, len = lines.length; i < len; i += 2) {
|
|
var match = lineRE.exec(lines[i]);
|
|
if (match) {
|
|
result.push(new StackFrame(undefined, undefined, match[2], match[1]));
|
|
}
|
|
}
|
|
|
|
return result;
|
|
},
|
|
|
|
parseOpera10: function ErrorStackParser$$parseOpera10(e) {
|
|
var lineRE = /Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$/i;
|
|
var lines = e.stacktrace.split('\n');
|
|
var result = [];
|
|
|
|
for (var i = 0, len = lines.length; i < len; i += 2) {
|
|
var match = lineRE.exec(lines[i]);
|
|
if (match) {
|
|
result.push(new StackFrame(match[3] || undefined, undefined, match[2], match[1]));
|
|
}
|
|
}
|
|
|
|
return result;
|
|
},
|
|
|
|
// Opera 10.65+ Error.stack very similar to FF/Safari
|
|
parseOpera11: function ErrorStackParser$$parseOpera11(error) {
|
|
return error.stack.split('\n').filter(function (line) {
|
|
return !!line.match(FIREFOX_SAFARI_STACK_REGEXP) &&
|
|
!line.match(/^Error created at/);
|
|
}, this).map(function (line) {
|
|
var tokens = line.split('@');
|
|
var locationParts = this.extractLocation(tokens.pop());
|
|
var functionCall = (tokens.shift() || '');
|
|
var functionName = functionCall
|
|
.replace(/<anonymous function(: (\w+))?>/, '$2')
|
|
.replace(/\([^\)]*\)/g, '') || undefined;
|
|
var argsRaw;
|
|
if (functionCall.match(/\(([^\)]*)\)/)) {
|
|
argsRaw = functionCall.replace(/^[^\(]+\(([^\)]*)\)$/, '$1');
|
|
}
|
|
var args = (argsRaw === undefined || argsRaw === '[arguments not available]') ? undefined : argsRaw.split(',');
|
|
return new StackFrame(functionName, args, locationParts[0], locationParts[1], locationParts[2]);
|
|
}, this);
|
|
}
|
|
};
|
|
}));
|
|
|