@airbrake/browser
Version:
Official Airbrake notifier for browsers
1,446 lines (1,322 loc) • 116 kB
JavaScript
/* airbrake-js v2.1.9 */
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Airbrake = {}));
})(this, (function (exports) { 'use strict';
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
/**
* @this {Promise}
*/
function finallyConstructor(callback) {
var constructor = this.constructor;
return this.then(
function(value) {
// @ts-ignore
return constructor.resolve(callback()).then(function() {
return value;
});
},
function(reason) {
// @ts-ignore
return constructor.resolve(callback()).then(function() {
// @ts-ignore
return constructor.reject(reason);
});
}
);
}
function allSettled(arr) {
var P = this;
return new P(function(resolve, reject) {
if (!(arr && typeof arr.length !== 'undefined')) {
return reject(
new TypeError(
typeof arr +
' ' +
arr +
' is not iterable(cannot read property Symbol(Symbol.iterator))'
)
);
}
var args = Array.prototype.slice.call(arr);
if (args.length === 0) return resolve([]);
var remaining = args.length;
function res(i, val) {
if (val && (typeof val === 'object' || typeof val === 'function')) {
var then = val.then;
if (typeof then === 'function') {
then.call(
val,
function(val) {
res(i, val);
},
function(e) {
args[i] = { status: 'rejected', reason: e };
if (--remaining === 0) {
resolve(args);
}
}
);
return;
}
}
args[i] = { status: 'fulfilled', value: val };
if (--remaining === 0) {
resolve(args);
}
}
for (var i = 0; i < args.length; i++) {
res(i, args[i]);
}
});
}
// Store setTimeout reference so promise-polyfill will be unaffected by
// other code modifying setTimeout (like sinon.useFakeTimers())
var setTimeoutFunc = setTimeout;
function isArray(x) {
return Boolean(x && typeof x.length !== 'undefined');
}
function noop() {}
// Polyfill for Function.prototype.bind
function bind(fn, thisArg) {
return function() {
fn.apply(thisArg, arguments);
};
}
/**
* @constructor
* @param {Function} fn
*/
function Promise$1(fn) {
if (!(this instanceof Promise$1))
throw new TypeError('Promises must be constructed via new');
if (typeof fn !== 'function') throw new TypeError('not a function');
/** @type {!number} */
this._state = 0;
/** @type {!boolean} */
this._handled = false;
/** @type {Promise|undefined} */
this._value = undefined;
/** @type {!Array<!Function>} */
this._deferreds = [];
doResolve(fn, this);
}
function handle(self, deferred) {
while (self._state === 3) {
self = self._value;
}
if (self._state === 0) {
self._deferreds.push(deferred);
return;
}
self._handled = true;
Promise$1._immediateFn(function() {
var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
if (cb === null) {
(self._state === 1 ? resolve : reject)(deferred.promise, self._value);
return;
}
var ret;
try {
ret = cb(self._value);
} catch (e) {
reject(deferred.promise, e);
return;
}
resolve(deferred.promise, ret);
});
}
function resolve(self, newValue) {
try {
// Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
if (newValue === self)
throw new TypeError('A promise cannot be resolved with itself.');
if (
newValue &&
(typeof newValue === 'object' || typeof newValue === 'function')
) {
var then = newValue.then;
if (newValue instanceof Promise$1) {
self._state = 3;
self._value = newValue;
finale(self);
return;
} else if (typeof then === 'function') {
doResolve(bind(then, newValue), self);
return;
}
}
self._state = 1;
self._value = newValue;
finale(self);
} catch (e) {
reject(self, e);
}
}
function reject(self, newValue) {
self._state = 2;
self._value = newValue;
finale(self);
}
function finale(self) {
if (self._state === 2 && self._deferreds.length === 0) {
Promise$1._immediateFn(function() {
if (!self._handled) {
Promise$1._unhandledRejectionFn(self._value);
}
});
}
for (var i = 0, len = self._deferreds.length; i < len; i++) {
handle(self, self._deferreds[i]);
}
self._deferreds = null;
}
/**
* @constructor
*/
function Handler(onFulfilled, onRejected, promise) {
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
this.onRejected = typeof onRejected === 'function' ? onRejected : null;
this.promise = promise;
}
/**
* Take a potentially misbehaving resolver function and make sure
* onFulfilled and onRejected are only called once.
*
* Makes no guarantees about asynchrony.
*/
function doResolve(fn, self) {
var done = false;
try {
fn(
function(value) {
if (done) return;
done = true;
resolve(self, value);
},
function(reason) {
if (done) return;
done = true;
reject(self, reason);
}
);
} catch (ex) {
if (done) return;
done = true;
reject(self, ex);
}
}
Promise$1.prototype['catch'] = function(onRejected) {
return this.then(null, onRejected);
};
Promise$1.prototype.then = function(onFulfilled, onRejected) {
// @ts-ignore
var prom = new this.constructor(noop);
handle(this, new Handler(onFulfilled, onRejected, prom));
return prom;
};
Promise$1.prototype['finally'] = finallyConstructor;
Promise$1.all = function(arr) {
return new Promise$1(function(resolve, reject) {
if (!isArray(arr)) {
return reject(new TypeError('Promise.all accepts an array'));
}
var args = Array.prototype.slice.call(arr);
if (args.length === 0) return resolve([]);
var remaining = args.length;
function res(i, val) {
try {
if (val && (typeof val === 'object' || typeof val === 'function')) {
var then = val.then;
if (typeof then === 'function') {
then.call(
val,
function(val) {
res(i, val);
},
reject
);
return;
}
}
args[i] = val;
if (--remaining === 0) {
resolve(args);
}
} catch (ex) {
reject(ex);
}
}
for (var i = 0; i < args.length; i++) {
res(i, args[i]);
}
});
};
Promise$1.allSettled = allSettled;
Promise$1.resolve = function(value) {
if (value && typeof value === 'object' && value.constructor === Promise$1) {
return value;
}
return new Promise$1(function(resolve) {
resolve(value);
});
};
Promise$1.reject = function(value) {
return new Promise$1(function(resolve, reject) {
reject(value);
});
};
Promise$1.race = function(arr) {
return new Promise$1(function(resolve, reject) {
if (!isArray(arr)) {
return reject(new TypeError('Promise.race accepts an array'));
}
for (var i = 0, len = arr.length; i < len; i++) {
Promise$1.resolve(arr[i]).then(resolve, reject);
}
});
};
// Use polyfill for setImmediate for performance gains
Promise$1._immediateFn =
// @ts-ignore
(typeof setImmediate === 'function' &&
function(fn) {
// @ts-ignore
setImmediate(fn);
}) ||
function(fn) {
setTimeoutFunc(fn, 0);
};
Promise$1._unhandledRejectionFn = function _unhandledRejectionFn(err) {
if (typeof console !== 'undefined' && console) {
console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console
}
};
var FILTERED = '[Filtered]';
var MAX_OBJ_LENGTH = 128;
// jsonifyNotice serializes notice to JSON and truncates params,
// environment and session keys.
function jsonifyNotice(notice, _a) {
var _b = _a === void 0 ? {} : _a, _c = _b.maxLength, maxLength = _c === void 0 ? 64000 : _c, _d = _b.keysBlocklist, keysBlocklist = _d === void 0 ? [] : _d, _e = _b.keysAllowlist, keysAllowlist = _e === void 0 ? [] : _e;
if (notice.errors) {
for (var i = 0; i < notice.errors.length; i++) {
var t = new Truncator({ keysBlocklist: keysBlocklist, keysAllowlist: keysAllowlist });
notice.errors[i] = t.truncate(notice.errors[i]);
}
}
var s = '';
var keys = ['params', 'environment', 'session'];
for (var level = 0; level < 8; level++) {
var opts = { level: level, keysBlocklist: keysBlocklist, keysAllowlist: keysAllowlist };
for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
var key = keys_1[_i];
var obj = notice[key];
if (obj) {
notice[key] = truncate(obj, opts);
}
}
s = JSON.stringify(notice);
if (s.length < maxLength) {
return s;
}
}
var params = {
json: s.slice(0, Math.floor(maxLength / 2)) + '...',
};
keys.push('errors');
for (var _f = 0, keys_2 = keys; _f < keys_2.length; _f++) {
var key = keys_2[_f];
var obj = notice[key];
if (!obj) {
continue;
}
s = JSON.stringify(obj);
params[key] = s.length;
}
var err = new Error("airbrake: notice exceeds max length and can't be truncated");
err.params = params;
throw err;
}
function scale(num, level) {
return num >> level || 1;
}
var Truncator = /** @class */ (function () {
function Truncator(opts) {
this.maxStringLength = 1024;
this.maxObjectLength = MAX_OBJ_LENGTH;
this.maxArrayLength = MAX_OBJ_LENGTH;
this.maxDepth = 8;
this.keys = [];
this.keysBlocklist = [];
this.keysAllowlist = [];
this.seen = [];
var level = opts.level || 0;
this.keysBlocklist = opts.keysBlocklist || [];
this.keysAllowlist = opts.keysAllowlist || [];
this.maxStringLength = scale(this.maxStringLength, level);
this.maxObjectLength = scale(this.maxObjectLength, level);
this.maxArrayLength = scale(this.maxArrayLength, level);
this.maxDepth = scale(this.maxDepth, level);
}
Truncator.prototype.truncate = function (value, key, depth) {
if (key === void 0) { key = ''; }
if (depth === void 0) { depth = 0; }
if (value === null || value === undefined) {
return value;
}
switch (typeof value) {
case 'boolean':
case 'number':
case 'function':
return value;
case 'string':
return this.truncateString(value);
case 'object':
break;
default:
return this.truncateString(String(value));
}
if (value instanceof String) {
return this.truncateString(value.toString());
}
if (value instanceof Boolean ||
value instanceof Number ||
value instanceof Date ||
value instanceof RegExp) {
return value;
}
if (value instanceof Error) {
return this.truncateString(value.toString());
}
if (this.seen.indexOf(value) >= 0) {
return "[Circular ".concat(this.getPath(value), "]");
}
var type = objectType(value);
depth++;
if (depth > this.maxDepth) {
return "[Truncated ".concat(type, "]");
}
this.keys.push(key);
this.seen.push(value);
switch (type) {
case 'Array':
return this.truncateArray(value, depth);
case 'Object':
return this.truncateObject(value, depth);
default:
var saved = this.maxDepth;
this.maxDepth = 0;
var obj = this.truncateObject(value, depth);
obj.__type = type;
this.maxDepth = saved;
return obj;
}
};
Truncator.prototype.getPath = function (value) {
var index = this.seen.indexOf(value);
var path = [this.keys[index]];
for (var i = index; i >= 0; i--) {
var sub = this.seen[i];
if (sub && getAttr(sub, path[0]) === value) {
value = sub;
path.unshift(this.keys[i]);
}
}
return '~' + path.join('.');
};
Truncator.prototype.truncateString = function (s) {
if (s.length > this.maxStringLength) {
return s.slice(0, this.maxStringLength) + '...';
}
return s;
};
Truncator.prototype.truncateArray = function (arr, depth) {
if (depth === void 0) { depth = 0; }
var length = 0;
var dst = [];
for (var i = 0; i < arr.length; i++) {
var el = arr[i];
dst.push(this.truncate(el, i.toString(), depth));
length++;
if (length >= this.maxArrayLength) {
break;
}
}
return dst;
};
Truncator.prototype.truncateObject = function (obj, depth) {
if (depth === void 0) { depth = 0; }
var length = 0;
var dst = {};
for (var key in obj) {
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
continue;
}
if (this.filterKey(key, dst))
continue;
var value = getAttr(obj, key);
if (value === undefined || typeof value === 'function') {
continue;
}
dst[key] = this.truncate(value, key, depth);
length++;
if (length >= this.maxObjectLength) {
break;
}
}
return dst;
};
Truncator.prototype.filterKey = function (key, obj) {
if ((this.keysAllowlist.length > 0 && !isInList(key, this.keysAllowlist)) ||
(this.keysAllowlist.length === 0 && isInList(key, this.keysBlocklist))) {
obj[key] = FILTERED;
return true;
}
return false;
};
return Truncator;
}());
function truncate(value, opts) {
if (opts === void 0) { opts = {}; }
var t = new Truncator(opts);
return t.truncate(value);
}
function getAttr(obj, attr) {
// Ignore browser specific exception trying to read an attribute (#79).
try {
return obj[attr];
}
catch (_) {
return;
}
}
function objectType(obj) {
var s = Object.prototype.toString.apply(obj);
return s.slice('[object '.length, -1);
}
function isInList(key, list) {
for (var _i = 0, list_1 = list; _i < list_1.length; _i++) {
var v = list_1[_i];
if (v === key) {
return true;
}
if (v instanceof RegExp) {
if (key.match(v)) {
return true;
}
}
}
return false;
}
var Span = /** @class */ (function () {
function Span(metric, name, startTime) {
this._dur = 0;
this._level = 0;
this._metric = metric;
this.name = name;
this.startTime = startTime || new Date();
}
Span.prototype.end = function (endTime) {
this.endTime = endTime ? endTime : new Date();
this._dur += this.endTime.getTime() - this.startTime.getTime();
this._metric._incGroup(this.name, this._dur);
this._metric = null;
};
Span.prototype._pause = function () {
if (this._paused()) {
return;
}
var now = new Date();
this._dur += now.getTime() - this.startTime.getTime();
this.startTime = null;
};
Span.prototype._resume = function () {
if (!this._paused()) {
return;
}
this.startTime = new Date();
};
Span.prototype._paused = function () {
return this.startTime == null;
};
return Span;
}());
var BaseMetric = /** @class */ (function () {
function BaseMetric() {
this._spans = {};
this._groups = {};
this.startTime = new Date();
}
BaseMetric.prototype.end = function (endTime) {
if (!this.endTime) {
this.endTime = endTime || new Date();
}
};
BaseMetric.prototype.isRecording = function () {
return true;
};
BaseMetric.prototype.startSpan = function (name, startTime) {
var span = this._spans[name];
if (span) {
span._level++;
}
else {
span = new Span(this, name, startTime);
this._spans[name] = span;
}
};
BaseMetric.prototype.endSpan = function (name, endTime) {
var span = this._spans[name];
if (!span) {
console.error('airbrake: span=%s does not exist', name);
return;
}
if (span._level > 0) {
span._level--;
}
else {
span.end(endTime);
delete this._spans[span.name];
}
};
BaseMetric.prototype._incGroup = function (name, ms) {
this._groups[name] = (this._groups[name] || 0) + ms;
};
BaseMetric.prototype._duration = function () {
if (!this.endTime) {
this.endTime = new Date();
}
return this.endTime.getTime() - this.startTime.getTime();
};
return BaseMetric;
}());
var NoopMetric = /** @class */ (function () {
function NoopMetric() {
}
NoopMetric.prototype.isRecording = function () {
return false;
};
NoopMetric.prototype.startSpan = function (_name, _startTime) { };
NoopMetric.prototype.endSpan = function (_name, _startTime) { };
NoopMetric.prototype._incGroup = function (_name, _ms) { };
return NoopMetric;
}());
var Scope = /** @class */ (function () {
function Scope() {
this._noopMetric = new NoopMetric();
this._context = {};
this._historyMaxLen = 20;
this._history = [];
}
Scope.prototype.clone = function () {
var clone = new Scope();
clone._context = __assign({}, this._context);
clone._history = this._history.slice();
return clone;
};
Scope.prototype.setContext = function (context) {
this._context = __assign(__assign({}, this._context), context);
};
Scope.prototype.context = function () {
var ctx = __assign({}, this._context);
if (this._history.length > 0) {
ctx.history = this._history.slice();
}
return ctx;
};
Scope.prototype.pushHistory = function (state) {
if (this._isDupState(state)) {
if (this._lastRecord.num) {
this._lastRecord.num++;
}
else {
this._lastRecord.num = 2;
}
return;
}
if (!state.date) {
state.date = new Date();
}
this._history.push(state);
this._lastRecord = state;
if (this._history.length > this._historyMaxLen) {
this._history = this._history.slice(-this._historyMaxLen);
}
};
Scope.prototype._isDupState = function (state) {
if (!this._lastRecord) {
return false;
}
for (var key in state) {
if (!state.hasOwnProperty(key) || key === 'date') {
continue;
}
if (state[key] !== this._lastRecord[key]) {
return false;
}
}
return true;
};
Scope.prototype.routeMetric = function () {
return this._routeMetric || this._noopMetric;
};
Scope.prototype.setRouteMetric = function (metric) {
this._routeMetric = metric;
};
Scope.prototype.queueMetric = function () {
return this._queueMetric || this._noopMetric;
};
Scope.prototype.setQueueMetric = function (metric) {
this._queueMetric = metric;
};
return Scope;
}());
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function getDefaultExportFromCjs (x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}
var errorStackParserExports = {};
var errorStackParser = {
get exports(){ return errorStackParserExports; },
set exports(v){ errorStackParserExports = v; },
};
var stackframeExports = {};
var stackframe = {
get exports(){ return stackframeExports; },
set exports(v){ stackframeExports = v; },
};
var hasRequiredStackframe;
function requireStackframe () {
if (hasRequiredStackframe) return stackframeExports;
hasRequiredStackframe = 1;
(function (module, exports) {
(function(root, factory) {
// Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, Rhino, and browsers.
/* istanbul ignore next */
{
module.exports = factory();
}
}(commonjsGlobal, function() {
function _isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
function _capitalize(str) {
return str.charAt(0).toUpperCase() + str.substring(1);
}
function _getter(p) {
return function() {
return this[p];
};
}
var booleanProps = ['isConstructor', 'isEval', 'isNative', 'isToplevel'];
var numericProps = ['columnNumber', 'lineNumber'];
var stringProps = ['fileName', 'functionName', 'source'];
var arrayProps = ['args'];
var objectProps = ['evalOrigin'];
var props = booleanProps.concat(numericProps, stringProps, arrayProps, objectProps);
function StackFrame(obj) {
if (!obj) return;
for (var i = 0; i < props.length; i++) {
if (obj[props[i]] !== undefined) {
this['set' + _capitalize(props[i])](obj[props[i]]);
}
}
}
StackFrame.prototype = {
getArgs: function() {
return this.args;
},
setArgs: function(v) {
if (Object.prototype.toString.call(v) !== '[object Array]') {
throw new TypeError('Args must be an Array');
}
this.args = v;
},
getEvalOrigin: function() {
return this.evalOrigin;
},
setEvalOrigin: function(v) {
if (v instanceof StackFrame) {
this.evalOrigin = v;
} else if (v instanceof Object) {
this.evalOrigin = new StackFrame(v);
} else {
throw new TypeError('Eval Origin must be an Object or StackFrame');
}
},
toString: function() {
var fileName = this.getFileName() || '';
var lineNumber = this.getLineNumber() || '';
var columnNumber = this.getColumnNumber() || '';
var functionName = this.getFunctionName() || '';
if (this.getIsEval()) {
if (fileName) {
return '[eval] (' + fileName + ':' + lineNumber + ':' + columnNumber + ')';
}
return '[eval]:' + lineNumber + ':' + columnNumber;
}
if (functionName) {
return functionName + ' (' + fileName + ':' + lineNumber + ':' + columnNumber + ')';
}
return fileName + ':' + lineNumber + ':' + columnNumber;
}
};
StackFrame.fromString = function StackFrame$$fromString(str) {
var argsStartIndex = str.indexOf('(');
var argsEndIndex = str.lastIndexOf(')');
var functionName = str.substring(0, argsStartIndex);
var args = str.substring(argsStartIndex + 1, argsEndIndex).split(',');
var locationString = str.substring(argsEndIndex + 1);
if (locationString.indexOf('@') === 0) {
var parts = /@(.+?)(?::(\d+))?(?::(\d+))?$/.exec(locationString, '');
var fileName = parts[1];
var lineNumber = parts[2];
var columnNumber = parts[3];
}
return new StackFrame({
functionName: functionName,
args: args || undefined,
fileName: fileName,
lineNumber: lineNumber || undefined,
columnNumber: columnNumber || undefined
});
};
for (var i = 0; i < booleanProps.length; i++) {
StackFrame.prototype['get' + _capitalize(booleanProps[i])] = _getter(booleanProps[i]);
StackFrame.prototype['set' + _capitalize(booleanProps[i])] = (function(p) {
return function(v) {
this[p] = Boolean(v);
};
})(booleanProps[i]);
}
for (var j = 0; j < numericProps.length; j++) {
StackFrame.prototype['get' + _capitalize(numericProps[j])] = _getter(numericProps[j]);
StackFrame.prototype['set' + _capitalize(numericProps[j])] = (function(p) {
return function(v) {
if (!_isNumber(v)) {
throw new TypeError(p + ' must be a Number');
}
this[p] = Number(v);
};
})(numericProps[j]);
}
for (var k = 0; k < stringProps.length; k++) {
StackFrame.prototype['get' + _capitalize(stringProps[k])] = _getter(stringProps[k]);
StackFrame.prototype['set' + _capitalize(stringProps[k])] = (function(p) {
return function(v) {
this[p] = String(v);
};
})(stringProps[k]);
}
return StackFrame;
}));
} (stackframe));
return stackframeExports;
}
(function (module, exports) {
(function(root, factory) {
// Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, Rhino, and browsers.
/* istanbul ignore next */
{
module.exports = factory(requireStackframe());
}
}(commonjsGlobal, function ErrorStackParser(StackFrame) {
var FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\S+:\d+/;
var CHROME_IE_STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/m;
var SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\[native code])?$/;
return {
/**
* Given an Error object, extract the most information from it.
*
* @param {Error} error object
* @return {Array} of StackFrames
*/
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) {
return this.parseFFOrSafari(error);
} else {
throw new Error('Cannot parse given Error object');
}
},
// Separate line and column numbers from a string of the form: (URI:Line:Column)
extractLocation: function ErrorStackParser$$extractLocation(urlLike) {
// Fail-fast but return locations like "(native)"
if (urlLike.indexOf(':') === -1) {
return [urlLike];
}
var regExp = /(.+?)(?::(\d+))?(?::(\d+))?$/;
var parts = regExp.exec(urlLike.replace(/[()]/g, ''));
return [parts[1], parts[2] || undefined, parts[3] || undefined];
},
parseV8OrIE: function ErrorStackParser$$parseV8OrIE(error) {
var filtered = error.stack.split('\n').filter(function(line) {
return !!line.match(CHROME_IE_STACK_REGEXP);
}, this);
return filtered.map(function(line) {
if (line.indexOf('(eval ') > -1) {
// Throw away eval information until we implement stacktrace.js/stackframe#8
line = line.replace(/eval code/g, 'eval').replace(/(\(eval at [^()]*)|(,.*$)/g, '');
}
var sanitizedLine = line.replace(/^\s+/, '').replace(/\(eval code/g, '(').replace(/^.*?\s+/, '');
// capture and preseve the parenthesized location "(/foo/my bar.js:12:87)" in
// case it has spaces in it, as the string is split on \s+ later on
var location = sanitizedLine.match(/ (\(.+\)$)/);
// remove the parenthesized location from the line, if it was matched
sanitizedLine = location ? sanitizedLine.replace(location[0], '') : sanitizedLine;
// if a location was matched, pass it to extractLocation() otherwise pass all sanitizedLine
// because this line doesn't have function name
var locationParts = this.extractLocation(location ? location[1] : sanitizedLine);
var functionName = location && sanitizedLine || undefined;
var fileName = ['eval', '<anonymous>'].indexOf(locationParts[0]) > -1 ? undefined : locationParts[0];
return new StackFrame({
functionName: functionName,
fileName: fileName,
lineNumber: locationParts[1],
columnNumber: locationParts[2],
source: line
});
}, this);
},
parseFFOrSafari: function ErrorStackParser$$parseFFOrSafari(error) {
var filtered = error.stack.split('\n').filter(function(line) {
return !line.match(SAFARI_NATIVE_CODE_REGEXP);
}, this);
return filtered.map(function(line) {
// Throw away eval information until we implement stacktrace.js/stackframe#8
if (line.indexOf(' > eval') > -1) {
line = line.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g, ':$1');
}
if (line.indexOf('@') === -1 && line.indexOf(':') === -1) {
// Safari eval frames only have function names and nothing else
return new StackFrame({
functionName: line
});
} else {
var functionNameRegex = /((.*".+"[^@]*)?[^@]*)(?:@)/;
var matches = line.match(functionNameRegex);
var functionName = matches && matches[1] ? matches[1] : undefined;
var locationParts = this.extractLocation(line.replace(functionNameRegex, ''));
return new StackFrame({
functionName: functionName,
fileName: locationParts[0],
lineNumber: locationParts[1],
columnNumber: locationParts[2],
source: line
});
}
}, 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({
fileName: match[2],
lineNumber: match[1],
source: lines[i]
}));
}
}
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({
functionName: match[3] || undefined,
fileName: match[2],
lineNumber: match[1],
source: lines[i]
})
);
}
}
return result;
},
// Opera 10.65+ Error.stack very similar to FF/Safari
parseOpera11: function ErrorStackParser$$parseOpera11(error) {
var filtered = error.stack.split('\n').filter(function(line) {
return !!line.match(FIREFOX_SAFARI_STACK_REGEXP) && !line.match(/^Error created at/);
}, this);
return filtered.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: functionName,
args: args,
fileName: locationParts[0],
lineNumber: locationParts[1],
columnNumber: locationParts[2],
source: line
});
}, this);
}
};
}));
} (errorStackParser));
var ErrorStackParser = errorStackParserExports;
var hasConsole = typeof console === 'object' && console.warn;
function parse(err) {
try {
return ErrorStackParser.parse(err);
}
catch (parseErr) {
if (hasConsole && err.stack) {
console.warn('ErrorStackParser:', parseErr.toString(), err.stack);
}
}
if (err.fileName) {
return [err];
}
return [];
}
function espProcessor(err) {
var backtrace = [];
if (err.noStack) {
backtrace.push({
function: err.functionName || '',
file: err.fileName || '',
line: err.lineNumber || 0,
column: err.columnNumber || 0,
});
}
else {
var frames_2 = parse(err);
if (frames_2.length === 0) {
try {
throw new Error('fake');
}
catch (fakeErr) {
frames_2 = parse(fakeErr);
frames_2.shift();
frames_2.shift();
}
}
for (var _i = 0, frames_1 = frames_2; _i < frames_1.length; _i++) {
var frame = frames_1[_i];
backtrace.push({
function: frame.functionName || '',
file: frame.fileName || '',
line: frame.lineNumber || 0,
column: frame.columnNumber || 0,
});
}
}
var type = err.name ? err.name : '';
var msg = err.message ? String(err.message) : String(err);
return {
type: type,
message: msg,
backtrace: backtrace,
};
}
var re$1 = new RegExp([
'^',
'\\[(\\$.+)\\]',
'\\s',
'([\\s\\S]+)',
'$',
].join(''));
function angularMessageFilter(notice) {
var err = notice.errors[0];
if (err.type !== '' && err.type !== 'Error') {
return notice;
}
var m = err.message.match(re$1);
if (m !== null) {
err.type = m[1];
err.message = m[2];
}
return notice;
}
function makeDebounceFilter() {
var lastNoticeJSON;
var timeout;
return function (notice) {
var s = JSON.stringify(notice.errors);
if (s === lastNoticeJSON) {
return null;
}
if (timeout) {
clearTimeout(timeout);
}
lastNoticeJSON = s;
timeout = setTimeout(function () {
lastNoticeJSON = '';
}, 1000);
return notice;
};
}
var IGNORED_MESSAGES = [
'Script error',
'Script error.',
'InvalidAccessError',
];
function ignoreNoiseFilter(notice) {
var err = notice.errors[0];
if (err.type === '' && IGNORED_MESSAGES.indexOf(err.message) !== -1) {
return null;
}
if (err.backtrace && err.backtrace.length > 0) {
var frame = err.backtrace[0];
if (frame.file === '<anonymous>') {
return null;
}
}
return notice;
}
var re = new RegExp([
'^',
'Uncaught\\s',
'(.+?)',
':\\s',
'(.+)',
'$',
].join(''));
function uncaughtMessageFilter(notice) {
var err = notice.errors[0];
if (err.type !== '' && err.type !== 'Error') {
return notice;
}
var m = err.message.match(re);
if (m !== null) {
err.type = m[1];
err.message = m[2];
}
return notice;
}
var browserPonyfillExports = {};
var browserPonyfill = {
get exports(){ return browserPonyfillExports; },
set exports(v){ browserPonyfillExports = v; },
};
(function (module, exports) {
var global = typeof self !== 'undefined' ? self : commonjsGlobal;
var __self__ = (function () {
function F() {
this.fetch = false;
this.DOMException = global.DOMException;
}
F.prototype = global;
return new F();
})();
(function(self) {
((function (exports) {
var support = {
searchParams: 'URLSearchParams' in self,
iterable: 'Symbol' in self && 'iterator' in Symbol,
blob:
'FileReader' in self &&
'Blob' in self &&
(function() {
try {
new Blob();
return true
} catch (e) {
return false
}
})(),
formData: 'FormData' in self,
arrayBuffer: 'ArrayBuffer' in self
};
function isDataView(obj) {
return obj && DataView.prototype.isPrototypeOf(obj)
}
if (support.arrayBuffer) {
var viewClasses = [
'[object Int8Array]',
'[object Uint8Array]',
'[object Uint8ClampedArray]',
'[object Int16Array]',
'[object Uint16Array]',
'[object Int32Array]',
'[object Uint32Array]',
'[object Float32Array]',
'[object Float64Array]'
];
var isArrayBufferView =
ArrayBuffer.isView ||
function(obj) {
return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
};
}
function normalizeName(name) {
if (typeof name !== 'string') {
name = String(name);
}
if (/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(name)) {
throw new TypeError('Invalid character in header field name')
}
return name.toLowerCase()
}
function normalizeValue(value) {
if (typeof value !== 'string') {
value = String(value);
}
return value
}
// Build a destructive iterator for the value list
function iteratorFor(items) {
var iterator = {
next: function() {
var value = items.shift();
return {done: value === undefined, value: value}
}
};
if (support.iterable) {
iterator[Symbol.iterator] = function() {
return iterator
};
}
return iterator
}
function Headers(headers) {
this.map = {};
if (headers instanceof Headers) {
headers.forEach(function(value, name) {
this.append(name, value);
}, this);
} else if (Array.isArray(headers)) {
headers.forEach(function(header) {
this.append(header[0], header[1]);
}, this);
} else if (headers) {
Object.getOwnPropertyNames(headers).forEach(function(name) {
this.append(name, headers[name]);
}, this);
}
}
Headers.prototype.append = function(name, value) {
name = normalizeName(name);
value = normalizeValue(value);
var oldValue = this.map[name];
this.map[name] = oldValue ? oldValue + ', ' + value : value;
};
Headers.prototype['delete'] = function(name) {
delete this.map[normalizeName(name)];
};
Headers.prototype.get = function(name) {
name = normalizeName(name);
return this.has(name) ? this.map[name] : null
};
Headers.prototype.has = function(name) {
return this.map.hasOwnProperty(normalizeName(name))
};
Headers.prototype.set = function(name, value) {
this.map[normalizeName(name)] = normalizeValue(value);
};
Headers.prototype.forEach = function(callback, thisArg) {
for (var name in this.map) {
if (this.map.hasOwnProperty(name)) {
callback.call(thisArg, this.map[name], name, this);
}
}
};
Headers.prototype.keys = function() {
var items = [];
this.forEach(function(value, name) {
items.push(name);
});
return iteratorFor(items)
};
Headers.prototype.values = function() {
var items = [];
this.forEach(function(value) {
items.push(value);
});
return iteratorFor(items)
};
Headers.prototype.entries = function() {
var items = [];
this.forEach(function(value, name) {
items.push([name, value]);
});
return iteratorFor(items)
};
if (support.iterable) {
Headers.prototype[Symbol.iterator] = Headers.prototype.entries;
}
function consumed(body) {
if (body.bodyUsed) {
return Promise.reject(new TypeError('Already read'))
}
body.bodyUsed = true;
}
function fileReaderReady(reader) {
return new Promise(function(resolve, reject) {
reader.onload = function() {
resolve(reader.result);
};
reader.onerror = function() {
reject(reader.error);
};
})
}