summaryrefslogtreecommitdiff
path: root/shared/logger/node_modules/@sentry/utils/esm/stacktrace.js
diff options
context:
space:
mode:
authorrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
committerrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
commitbce557cc2dc767628bed6aac87301a1be7c5431b (patch)
treeb51a051228d01fe3306cd7626d4a96768aadb944 /shared/logger/node_modules/@sentry/utils/esm/stacktrace.js
init commit
Diffstat (limited to 'shared/logger/node_modules/@sentry/utils/esm/stacktrace.js')
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/stacktrace.js136
1 files changed, 136 insertions, 0 deletions
diff --git a/shared/logger/node_modules/@sentry/utils/esm/stacktrace.js b/shared/logger/node_modules/@sentry/utils/esm/stacktrace.js
new file mode 100644
index 0000000..ffb3614
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/stacktrace.js
@@ -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