forked from off-topic/apps.apple.com
init commit
This commit is contained in:
136
shared/logger/node_modules/@sentry/utils/esm/stacktrace.js
generated
vendored
Normal file
136
shared/logger/node_modules/@sentry/utils/esm/stacktrace.js
generated
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
import { node } from './node-stack-trace.js';
|
||||
|
||||
const STACKTRACE_FRAME_LIMIT = 50;
|
||||
// Used to sanitize webpack (error: *) wrapped stack errors
|
||||
const WEBPACK_ERROR_REGEXP = /\(error: (.*)\)/;
|
||||
|
||||
/**
|
||||
* Creates a stack parser with the supplied line parsers
|
||||
*
|
||||
* StackFrames are returned in the correct order for Sentry Exception
|
||||
* frames and with Sentry SDK internal frames removed from the top and bottom
|
||||
*
|
||||
*/
|
||||
function createStackParser(...parsers) {
|
||||
const sortedParsers = parsers.sort((a, b) => a[0] - b[0]).map(p => p[1]);
|
||||
|
||||
return (stack, skipFirst = 0) => {
|
||||
const frames = [];
|
||||
const lines = stack.split('\n');
|
||||
|
||||
for (let i = skipFirst; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
// Ignore lines over 1kb as they are unlikely to be stack frames.
|
||||
// Many of the regular expressions use backtracking which results in run time that increases exponentially with
|
||||
// input size. Huge strings can result in hangs/Denial of Service:
|
||||
// https://github.com/getsentry/sentry-javascript/issues/2286
|
||||
if (line.length > 1024) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// https://github.com/getsentry/sentry-javascript/issues/5459
|
||||
// Remove webpack (error: *) wrappers
|
||||
const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, '$1') : line;
|
||||
|
||||
// https://github.com/getsentry/sentry-javascript/issues/7813
|
||||
// Skip Error: lines
|
||||
if (cleanedLine.match(/\S*Error: /)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const parser of sortedParsers) {
|
||||
const frame = parser(cleanedLine);
|
||||
|
||||
if (frame) {
|
||||
frames.push(frame);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (frames.length >= STACKTRACE_FRAME_LIMIT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return stripSentryFramesAndReverse(frames);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a stack parser implementation from Options.stackParser
|
||||
* @see Options
|
||||
*
|
||||
* If options contains an array of line parsers, it is converted into a parser
|
||||
*/
|
||||
function stackParserFromStackParserOptions(stackParser) {
|
||||
if (Array.isArray(stackParser)) {
|
||||
return createStackParser(...stackParser);
|
||||
}
|
||||
return stackParser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes Sentry frames from the top and bottom of the stack if present and enforces a limit of max number of frames.
|
||||
* Assumes stack input is ordered from top to bottom and returns the reverse representation so call site of the
|
||||
* function that caused the crash is the last frame in the array.
|
||||
* @hidden
|
||||
*/
|
||||
function stripSentryFramesAndReverse(stack) {
|
||||
if (!stack.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const localStack = stack.slice(0, STACKTRACE_FRAME_LIMIT);
|
||||
|
||||
const lastFrameFunction = localStack[localStack.length - 1].function;
|
||||
// If stack starts with one of our API calls, remove it (starts, meaning it's the top of the stack - aka last call)
|
||||
if (lastFrameFunction && /sentryWrapped/.test(lastFrameFunction)) {
|
||||
localStack.pop();
|
||||
}
|
||||
|
||||
// Reversing in the middle of the procedure allows us to just pop the values off the stack
|
||||
localStack.reverse();
|
||||
|
||||
const firstFrameFunction = localStack[localStack.length - 1].function;
|
||||
// If stack ends with one of our internal API calls, remove it (ends, meaning it's the bottom of the stack - aka top-most call)
|
||||
if (firstFrameFunction && /captureMessage|captureException/.test(firstFrameFunction)) {
|
||||
localStack.pop();
|
||||
}
|
||||
|
||||
return localStack.map(frame => ({
|
||||
...frame,
|
||||
filename: frame.filename || localStack[localStack.length - 1].filename,
|
||||
function: frame.function || '?',
|
||||
}));
|
||||
}
|
||||
|
||||
const defaultFunctionName = '<anonymous>';
|
||||
|
||||
/**
|
||||
* Safely extract function name from itself
|
||||
*/
|
||||
function getFunctionName(fn) {
|
||||
try {
|
||||
if (!fn || typeof fn !== 'function') {
|
||||
return defaultFunctionName;
|
||||
}
|
||||
return fn.name || defaultFunctionName;
|
||||
} catch (e) {
|
||||
// Just accessing custom props in some Selenium environments
|
||||
// can cause a "Permission denied" exception (see raven-js#495).
|
||||
return defaultFunctionName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Node.js stack line parser
|
||||
*
|
||||
* This is in @sentry/utils so it can be used from the Electron SDK in the browser for when `nodeIntegration == true`.
|
||||
* This allows it to be used without referencing or importing any node specific code which causes bundlers to complain
|
||||
*/
|
||||
function nodeStackLineParser(getModule) {
|
||||
return [90, node(getModule)];
|
||||
}
|
||||
|
||||
export { createStackParser, getFunctionName, nodeStackLineParser, stackParserFromStackParserOptions, stripSentryFramesAndReverse };
|
||||
//# sourceMappingURL=stacktrace.js.map
|
||||
Reference in New Issue
Block a user