From 96eec8ea270926d29a2c8e9d63d59c189a411d7b Mon Sep 17 00:00:00 2001 From: Tim Fish Date: Mon, 19 Feb 2024 21:04:55 -0400 Subject: [PATCH 1/3] fix(stacktrace): Always use `?` for anonymous function name --- packages/browser/src/integrations/globalhandlers.ts | 3 ++- packages/browser/src/stack-parsers.ts | 7 ++----- packages/browser/test/unit/tracekit/misc.test.ts | 2 +- packages/deno/test/__snapshots__/mod.test.ts.snap | 2 +- packages/node/test/stacktrace.test.ts | 6 +++--- packages/utils/src/anr.ts | 4 ++-- packages/utils/src/node-stack-trace.ts | 3 ++- packages/utils/src/stacktrace.ts | 3 ++- packages/utils/test/stacktrace.test.ts | 12 ++++++------ 9 files changed, 21 insertions(+), 21 deletions(-) diff --git a/packages/browser/src/integrations/globalhandlers.ts b/packages/browser/src/integrations/globalhandlers.ts index e2aa0b6116f0..b57fd8383155 100644 --- a/packages/browser/src/integrations/globalhandlers.ts +++ b/packages/browser/src/integrations/globalhandlers.ts @@ -1,6 +1,7 @@ import { captureEvent, defineIntegration, getClient } from '@sentry/core'; import type { Client, Event, IntegrationFn, Primitive, StackParser } from '@sentry/types'; import { + UNKNOWN_FUNCTION, addGlobalErrorInstrumentationHandler, addGlobalUnhandledRejectionInstrumentationHandler, getLocationHref, @@ -172,7 +173,7 @@ function _enhanceEventWithInitialFrame(event: Event, url: any, line: any, column ev0sf.push({ colno, filename, - function: '?', + function: UNKNOWN_FUNCTION, in_app: true, lineno, }); diff --git a/packages/browser/src/stack-parsers.ts b/packages/browser/src/stack-parsers.ts index 609a6dd1fd51..effe7538178b 100644 --- a/packages/browser/src/stack-parsers.ts +++ b/packages/browser/src/stack-parsers.ts @@ -24,10 +24,7 @@ // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import type { StackFrame, StackLineParser, StackLineParserFn } from '@sentry/types'; -import { createStackParser } from '@sentry/utils'; - -// global reference to slice -const UNKNOWN_FUNCTION = '?'; +import { UNKNOWN_FUNCTION, createStackParser } from '@sentry/utils'; const OPERA10_PRIORITY = 10; const OPERA11_PRIORITY = 20; @@ -38,7 +35,7 @@ const GECKO_PRIORITY = 50; function createFrame(filename: string, func: string, lineno?: number, colno?: number): StackFrame { const frame: StackFrame = { filename, - function: func, + function: func === '' ? UNKNOWN_FUNCTION : func, in_app: true, // All browser frames are considered in_app }; diff --git a/packages/browser/test/unit/tracekit/misc.test.ts b/packages/browser/test/unit/tracekit/misc.test.ts index b092c8d10723..8cb31f9a7868 100644 --- a/packages/browser/test/unit/tracekit/misc.test.ts +++ b/packages/browser/test/unit/tracekit/misc.test.ts @@ -92,7 +92,7 @@ describe('Tracekit - Misc Tests', () => { { filename: '', function: 'Array.forEach', in_app: true }, { filename: '../node_modules/@sentry-internal/rrweb/es/rrweb/ext/@xstate/fsm/es/index.js', - function: '', + function: '?', in_app: true, lineno: 15, colno: 2595, diff --git a/packages/deno/test/__snapshots__/mod.test.ts.snap b/packages/deno/test/__snapshots__/mod.test.ts.snap index 417acf1e7639..6cbbe0182902 100644 --- a/packages/deno/test/__snapshots__/mod.test.ts.snap +++ b/packages/deno/test/__snapshots__/mod.test.ts.snap @@ -45,7 +45,7 @@ snapshot[`captureException 1`] = ` colno: 27, context_line: " client.captureException(something());", filename: "app:///test/mod.test.ts", - function: "", + function: "?", in_app: true, lineno: 47, post_context: [ diff --git a/packages/node/test/stacktrace.test.ts b/packages/node/test/stacktrace.test.ts index edd62c81d8e5..968cdccca9a4 100644 --- a/packages/node/test/stacktrace.test.ts +++ b/packages/node/test/stacktrace.test.ts @@ -193,7 +193,7 @@ describe('Stack parsing', () => { { filename: '/Users/felix/code/node-fast-or-slow/lib/test_case.js', module: 'test_case', - function: '', + function: '?', lineno: 80, colno: 10, in_app: true, @@ -213,7 +213,7 @@ describe('Stack parsing', () => { { filename: '/Users/felix/code/node-fast-or-slow/lib/test_case.js', module: 'test_case', - function: '', + function: '?', lineno: 80, colno: 10, in_app: true, @@ -290,7 +290,7 @@ describe('Stack parsing', () => { { filename: '/code/node_modules/kafkajs/src/consumer/runner.js', module: 'kafkajs.src.consumer:runner', - function: '', + function: '?', lineno: 376, colno: 15, in_app: false, diff --git a/packages/utils/src/anr.ts b/packages/utils/src/anr.ts index d962107bcb0e..5df0ceecdc42 100644 --- a/packages/utils/src/anr.ts +++ b/packages/utils/src/anr.ts @@ -1,7 +1,7 @@ import type { StackFrame } from '@sentry/types'; import { dropUndefinedKeys } from './object'; -import { filenameIsInApp } from './stacktrace'; +import { UNKNOWN_FUNCTION, filenameIsInApp } from './stacktrace'; type WatchdogReturn = { /** Resets the watchdog timer */ @@ -84,7 +84,7 @@ export function callFrameToStackFrame( return dropUndefinedKeys({ filename, module: getModuleFromFilename(filename), - function: frame.functionName || '?', + function: frame.functionName || UNKNOWN_FUNCTION, colno, lineno, in_app: filename ? filenameIsInApp(filename) : undefined, diff --git a/packages/utils/src/node-stack-trace.ts b/packages/utils/src/node-stack-trace.ts index 3b486be9148c..c706169fe88d 100644 --- a/packages/utils/src/node-stack-trace.ts +++ b/packages/utils/src/node-stack-trace.ts @@ -22,6 +22,7 @@ // THE SOFTWARE. import type { StackLineParserFn } from '@sentry/types'; +import { UNKNOWN_FUNCTION } from './stacktrace'; export type GetModuleFn = (filename: string | undefined) => string | undefined; @@ -96,7 +97,7 @@ export function node(getModule?: GetModuleFn): StackLineParserFn { } if (functionName === undefined) { - methodName = methodName || ''; + methodName = methodName || UNKNOWN_FUNCTION; functionName = typeName ? `${typeName}.${methodName}` : methodName; } diff --git a/packages/utils/src/stacktrace.ts b/packages/utils/src/stacktrace.ts index 917b46daa5d1..a3da0a2e9275 100644 --- a/packages/utils/src/stacktrace.ts +++ b/packages/utils/src/stacktrace.ts @@ -6,6 +6,7 @@ import { filenameIsInApp, node } from './node-stack-trace'; export { filenameIsInApp }; const STACKTRACE_FRAME_LIMIT = 50; +export const UNKNOWN_FUNCTION = '?'; // Used to sanitize webpack (error: *) wrapped stack errors const WEBPACK_ERROR_REGEXP = /\(error: (.*)\)/; const STRIP_FRAME_REGEXP = /captureMessage|captureException/; @@ -116,7 +117,7 @@ export function stripSentryFramesAndReverse(stack: ReadonlyArray): S return localStack.slice(0, STACKTRACE_FRAME_LIMIT).map(frame => ({ ...frame, filename: frame.filename || localStack[localStack.length - 1].filename, - function: frame.function || '?', + function: frame.function || UNKNOWN_FUNCTION, })); } diff --git a/packages/utils/test/stacktrace.test.ts b/packages/utils/test/stacktrace.test.ts index 4e87399b91db..097a09296a84 100644 --- a/packages/utils/test/stacktrace.test.ts +++ b/packages/utils/test/stacktrace.test.ts @@ -157,7 +157,7 @@ describe('node', () => { const expectedOutput = { filename: '/path/to/file.js', module: undefined, - function: '', + function: '?', lineno: 10, colno: 5, in_app: true, @@ -257,7 +257,7 @@ describe('node', () => { expect(result).toEqual({ filename: '/path/to/myFile.js', - function: 'Object.', + function: 'Object.?', lineno: 10, colno: 20, in_app: true, @@ -269,7 +269,7 @@ describe('node', () => { const result = node(line); expect(result).toEqual({ filename: '/path/to/myFile.js', - function: '', + function: '?', lineno: 10, colno: 20, in_app: true, @@ -281,7 +281,7 @@ describe('node', () => { const result = node(line); expect(result).toEqual({ filename: undefined, - function: 'Object.', + function: 'Object.?', lineno: undefined, colno: undefined, in_app: false, @@ -294,7 +294,7 @@ describe('node', () => { expect(result).toEqual({ filename: '/path/to/node_modules/myModule/index.js', - function: 'Object.', + function: 'Object.?', lineno: 10, colno: 20, in_app: false, @@ -306,7 +306,7 @@ describe('node', () => { const result = node(line); expect(result).toEqual({ filename: 'C:\\path\\to\\myFile.js', - function: 'Object.', + function: 'Object.?', lineno: 10, colno: 20, in_app: true, From f982d89c63a9ba45907923315f0b219aee4a225a Mon Sep 17 00:00:00 2001 From: Tim Fish Date: Mon, 19 Feb 2024 21:28:03 -0400 Subject: [PATCH 2/3] fix circular dependency --- packages/utils/src/anr.ts | 4 ++-- packages/utils/src/index.ts | 1 + packages/utils/src/node-stack-trace.ts | 12 +++++++++++- packages/utils/src/stacktrace.ts | 15 --------------- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/packages/utils/src/anr.ts b/packages/utils/src/anr.ts index 5df0ceecdc42..839903de062c 100644 --- a/packages/utils/src/anr.ts +++ b/packages/utils/src/anr.ts @@ -1,7 +1,7 @@ import type { StackFrame } from '@sentry/types'; - +import { filenameIsInApp } from './node-stack-trace'; import { dropUndefinedKeys } from './object'; -import { UNKNOWN_FUNCTION, filenameIsInApp } from './stacktrace'; +import { UNKNOWN_FUNCTION } from './stacktrace'; type WatchdogReturn = { /** Resets the watchdog timer */ diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index d19991b7d401..5c714e8fbd28 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -18,6 +18,7 @@ export * from './promisebuffer'; export * from './requestdata'; export * from './severity'; export * from './stacktrace'; +export * from './node-stack-trace'; export * from './string'; export * from './supports'; export * from './syncpromise'; diff --git a/packages/utils/src/node-stack-trace.ts b/packages/utils/src/node-stack-trace.ts index c706169fe88d..be858433d43a 100644 --- a/packages/utils/src/node-stack-trace.ts +++ b/packages/utils/src/node-stack-trace.ts @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -import type { StackLineParserFn } from '@sentry/types'; +import type { StackLineParser, StackLineParserFn } from '@sentry/types'; import { UNKNOWN_FUNCTION } from './stacktrace'; export type GetModuleFn = (filename: string | undefined) => string | undefined; @@ -132,3 +132,13 @@ export function node(getModule?: GetModuleFn): StackLineParserFn { return undefined; }; } + +/** + * 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 + */ +export function nodeStackLineParser(getModule?: GetModuleFn): StackLineParser { + return [90, node(getModule)]; +} diff --git a/packages/utils/src/stacktrace.ts b/packages/utils/src/stacktrace.ts index a3da0a2e9275..3fbecec82ebf 100644 --- a/packages/utils/src/stacktrace.ts +++ b/packages/utils/src/stacktrace.ts @@ -1,10 +1,5 @@ import type { StackFrame, StackLineParser, StackParser } from '@sentry/types'; -import type { GetModuleFn } from './node-stack-trace'; -import { filenameIsInApp, node } from './node-stack-trace'; - -export { filenameIsInApp }; - const STACKTRACE_FRAME_LIMIT = 50; export const UNKNOWN_FUNCTION = '?'; // Used to sanitize webpack (error: *) wrapped stack errors @@ -138,13 +133,3 @@ export function getFunctionName(fn: unknown): string { 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 - */ -export function nodeStackLineParser(getModule?: GetModuleFn): StackLineParser { - return [90, node(getModule)]; -} From ed094d5c93485decf00dd193a2e3dfd5c98fbc45 Mon Sep 17 00:00:00 2001 From: Tim Fish Date: Mon, 19 Feb 2024 21:44:56 -0400 Subject: [PATCH 3/3] Fix test --- packages/utils/test/stacktrace.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/utils/test/stacktrace.test.ts b/packages/utils/test/stacktrace.test.ts index 097a09296a84..7e5251d0dd9c 100644 --- a/packages/utils/test/stacktrace.test.ts +++ b/packages/utils/test/stacktrace.test.ts @@ -1,4 +1,4 @@ -import { nodeStackLineParser, stripSentryFramesAndReverse } from '../src/stacktrace'; +import { nodeStackLineParser, stripSentryFramesAndReverse } from '../src'; describe('Stacktrace', () => { describe('stripSentryFramesAndReverse()', () => {