sentry-uniapp
Version:
用于Uniapp/小程序/快应用等平台的 Sentry SDK
222 lines • 8.29 kB
JavaScript
// tslint:disable:object-literal-sort-keys
Object.defineProperty(exports, "__esModule", { value: true });
exports.computeStackTrace = void 0;
var tslib_1 = require("tslib");
// global reference to slice
var UNKNOWN_FUNCTION = "?";
// Chromium based browsers: Chrome, Brave, new Opera, new Edge
var chrome = /^\s*at (?:(.*?) ?\()?((?:file|https?|blob|chrome-extension|native|eval|webpack|<anonymous>|[-a-z]+:|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
// gecko regex: `(?:bundle|\d+\.js)`: `bundle` is for react native, `\d+\.js` also but specifically for ram bundles because it
// generates filenames without a prefix like `file://` the filenames in the stacktrace are just 42.js
// We need this specific case for now because we want no other regex to match.
var gecko = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:file|https?|blob|chrome|webpack|resource|moz-extension).*?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js))(?::(\d+))?(?::(\d+))?\s*$/i;
var winjs = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
var geckoEval = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
var chromeEval = /\((\S*)(?::(\d+))(?::(\d+))\)/;
var miniapp = /^\s*at (\w.*) \((\w*.js):(\d*):(\d*)/i;
/** JSDoc */
function computeStackTrace(ex) {
// console.log('computeStackTrace', ex)
// tslint:disable:no-unsafe-any
var stack = null;
var popSize = ex && ex.framesToPop;
try {
// This must be tried first because Opera 10 *destroys*
// its stacktrace property if you try to access the stack
// property first!!
stack = computeStackTraceFromStacktraceProp(ex);
if (stack) {
// console.log('computeStackTraceFromStacktraceProp', stack, popSize, popFrames(stack, popSize))
return popFrames(stack, popSize);
}
}
catch (e) {
// no-empty
}
try {
stack = computeStackTraceFromStackProp(ex);
if (stack) {
// console.log('computeStackTraceFromStackProp', stack, popSize, popFrames(stack, popSize))
return popFrames(stack, popSize);
}
}
catch (e) {
// no-empty
}
return {
message: extractMessage(ex),
name: ex && ex.name,
stack: [],
failed: true,
};
}
exports.computeStackTrace = computeStackTrace;
/** JSDoc */
// tslint:disable-next-line:cyclomatic-complexity
function computeStackTraceFromStackProp(ex) {
// tslint:disable:no-conditional-assignment
if (!ex || !ex.stack) {
return null;
}
var stack = [];
var lines = ex.stack.split("\n");
var isEval;
var submatch;
var parts;
var element;
// console.log('lines', lines)
for (var i = 0; i < lines.length; ++i) {
// console.log(lines[i], chrome.exec(lines[i]), winjs.exec(lines[i]), gecko.exec(lines[i]))
if ((parts = chrome.exec(lines[i]))) {
var isNative = parts[2] && parts[2].indexOf("native") === 0; // start of line
isEval = parts[2] && parts[2].indexOf("eval") === 0; // start of line
if (isEval && (submatch = chromeEval.exec(parts[2]))) {
// throw out eval line/column and use top-most line/column number
parts[2] = submatch[1]; // url
parts[3] = submatch[2]; // line
parts[4] = submatch[3]; // column
}
element = {
url: parts[2],
func: parts[1] || UNKNOWN_FUNCTION,
args: isNative ? [parts[2]] : [],
line: parts[3] ? +parts[3] : null,
column: parts[4] ? +parts[4] : null,
};
}
else if ((parts = winjs.exec(lines[i]))) {
element = {
url: parts[2],
func: parts[1] || UNKNOWN_FUNCTION,
args: [],
line: +parts[3],
column: parts[4] ? +parts[4] : null,
};
}
else if ((parts = gecko.exec(lines[i]))) {
isEval = parts[3] && parts[3].indexOf(" > eval") > -1;
if (isEval && (submatch = geckoEval.exec(parts[3]))) {
// throw out eval line/column and use top-most line number
parts[1] = parts[1] || "eval";
parts[3] = submatch[1];
parts[4] = submatch[2];
parts[5] = ""; // no column when eval
}
else if (i === 0 && !parts[5] && ex.columnNumber !== void 0) {
// FireFox uses this awesome columnNumber property for its top frame
// Also note, Firefox's column number is 0-based and everything else expects 1-based,
// so adding 1
// NOTE: this hack doesn't work if top-most frame is eval
stack[0].column = ex.columnNumber + 1;
}
element = {
url: parts[3],
func: parts[1] || UNKNOWN_FUNCTION,
args: parts[2] ? parts[2].split(",") : [],
line: parts[4] ? +parts[4] : null,
column: parts[5] ? +parts[5] : null,
};
}
else if ((parts = miniapp.exec(lines[i]))) {
element = {
url: parts[2],
func: parts[1] || UNKNOWN_FUNCTION,
args: [],
line: parts[3] ? +parts[3] : null,
column: parts[4] ? +parts[4] : null,
};
}
else {
continue;
}
if (!element.func && element.line) {
element.func = UNKNOWN_FUNCTION;
}
stack.push(element);
}
if (!stack.length) {
return null;
}
return {
message: extractMessage(ex),
name: ex.name,
stack: stack,
};
}
/** JSDoc */
function computeStackTraceFromStacktraceProp(ex) {
if (!ex || !ex.stacktrace) {
return null;
}
// Access and store the stacktrace property before doing ANYTHING
// else to it because Opera is not very good at providing it
// reliably in other circumstances.
var stacktrace = ex.stacktrace;
var opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i;
var opera11Regex = / line (\d+), column (\d+)\s*(?:in (?:<anonymous function: ([^>]+)>|([^\)]+))\((.*)\))? in (.*):\s*$/i;
var lines = stacktrace.split("\n");
var stack = [];
var parts;
for (var line = 0; line < lines.length; line += 2) {
// tslint:disable:no-conditional-assignment
var element = null;
if ((parts = opera10Regex.exec(lines[line]))) {
element = {
url: parts[2],
func: parts[3],
args: [],
line: +parts[1],
column: null,
};
}
else if ((parts = opera11Regex.exec(lines[line]))) {
element = {
url: parts[6],
func: parts[3] || parts[4],
args: parts[5] ? parts[5].split(",") : [],
line: +parts[1],
column: +parts[2],
};
}
if (element) {
if (!element.func && element.line) {
element.func = UNKNOWN_FUNCTION;
}
stack.push(element);
}
}
if (!stack.length) {
return null;
}
return {
message: extractMessage(ex),
name: ex.name,
stack: stack,
};
}
/** Remove N number of frames from the stack */
function popFrames(stacktrace, popSize) {
try {
return tslib_1.__assign(tslib_1.__assign({}, stacktrace), { stack: stacktrace.stack.slice(popSize) });
}
catch (e) {
return stacktrace;
}
}
/**
* There are cases where stacktrace.message is an Event object
* https://github.com/getsentry/sentry-javascript/issues/1949
* In this specific case we try to extract stacktrace.message.error.message
*/
function extractMessage(ex) {
var message = ex && ex.message;
// console.log('message',message)
if (!message) {
return "No error message";
}
if (message.error && typeof message.error.message === "string") {
return message.error.message;
}
return message;
}
//# sourceMappingURL=tracekit.js.map