Skip to content

Commit db8f26e

Browse files
authored
fix(stacktrace): Always use ? for anonymous function name (#10732)
This was previously opened as #5664 but closed as it was a breaking change. Now that we're getting ready to ship, v8 this is viable!
1 parent f402652 commit db8f26e

File tree

10 files changed

+35
-39
lines changed

10 files changed

+35
-39
lines changed

packages/browser/src/integrations/globalhandlers.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { captureEvent, defineIntegration, getClient } from '@sentry/core';
22
import type { Client, Event, IntegrationFn, Primitive, StackParser } from '@sentry/types';
33
import {
4+
UNKNOWN_FUNCTION,
45
addGlobalErrorInstrumentationHandler,
56
addGlobalUnhandledRejectionInstrumentationHandler,
67
getLocationHref,
@@ -172,7 +173,7 @@ function _enhanceEventWithInitialFrame(event: Event, url: any, line: any, column
172173
ev0sf.push({
173174
colno,
174175
filename,
175-
function: '?',
176+
function: UNKNOWN_FUNCTION,
176177
in_app: true,
177178
lineno,
178179
});

packages/browser/src/stack-parsers.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,7 @@
2424
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2525

2626
import type { StackFrame, StackLineParser, StackLineParserFn } from '@sentry/types';
27-
import { createStackParser } from '@sentry/utils';
28-
29-
// global reference to slice
30-
const UNKNOWN_FUNCTION = '?';
27+
import { UNKNOWN_FUNCTION, createStackParser } from '@sentry/utils';
3128

3229
const OPERA10_PRIORITY = 10;
3330
const OPERA11_PRIORITY = 20;
@@ -38,7 +35,7 @@ const GECKO_PRIORITY = 50;
3835
function createFrame(filename: string, func: string, lineno?: number, colno?: number): StackFrame {
3936
const frame: StackFrame = {
4037
filename,
41-
function: func,
38+
function: func === '<anonymous>' ? UNKNOWN_FUNCTION : func,
4239
in_app: true, // All browser frames are considered in_app
4340
};
4441

packages/browser/test/unit/tracekit/misc.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ describe('Tracekit - Misc Tests', () => {
9292
{ filename: '<anonymous>', function: 'Array.forEach', in_app: true },
9393
{
9494
filename: '../node_modules/@sentry-internal/rrweb/es/rrweb/ext/@xstate/fsm/es/index.js',
95-
function: '<anonymous>',
95+
function: '?',
9696
in_app: true,
9797
lineno: 15,
9898
colno: 2595,

packages/deno/test/__snapshots__/mod.test.ts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ snapshot[`captureException 1`] = `
4545
colno: 27,
4646
context_line: " client.captureException(something());",
4747
filename: "app:///test/mod.test.ts",
48-
function: "<anonymous>",
48+
function: "?",
4949
in_app: true,
5050
lineno: 47,
5151
post_context: [

packages/node/test/stacktrace.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ describe('Stack parsing', () => {
193193
{
194194
filename: '/Users/felix/code/node-fast-or-slow/lib/test_case.js',
195195
module: 'test_case',
196-
function: '<anonymous>',
196+
function: '?',
197197
lineno: 80,
198198
colno: 10,
199199
in_app: true,
@@ -213,7 +213,7 @@ describe('Stack parsing', () => {
213213
{
214214
filename: '/Users/felix/code/node-fast-or-slow/lib/test_case.js',
215215
module: 'test_case',
216-
function: '<anonymous>',
216+
function: '?',
217217
lineno: 80,
218218
colno: 10,
219219
in_app: true,
@@ -290,7 +290,7 @@ describe('Stack parsing', () => {
290290
{
291291
filename: '/code/node_modules/kafkajs/src/consumer/runner.js',
292292
module: 'kafkajs.src.consumer:runner',
293-
function: '<anonymous>',
293+
function: '?',
294294
lineno: 376,
295295
colno: 15,
296296
in_app: false,

packages/utils/src/anr.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { StackFrame } from '@sentry/types';
2-
2+
import { filenameIsInApp } from './node-stack-trace';
33
import { dropUndefinedKeys } from './object';
4-
import { filenameIsInApp } from './stacktrace';
4+
import { UNKNOWN_FUNCTION } from './stacktrace';
55

66
type WatchdogReturn = {
77
/** Resets the watchdog timer */
@@ -84,7 +84,7 @@ export function callFrameToStackFrame(
8484
return dropUndefinedKeys({
8585
filename,
8686
module: getModuleFromFilename(filename),
87-
function: frame.functionName || '?',
87+
function: frame.functionName || UNKNOWN_FUNCTION,
8888
colno,
8989
lineno,
9090
in_app: filename ? filenameIsInApp(filename) : undefined,

packages/utils/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export * from './promisebuffer';
1818
export * from './requestdata';
1919
export * from './severity';
2020
export * from './stacktrace';
21+
export * from './node-stack-trace';
2122
export * from './string';
2223
export * from './supports';
2324
export * from './syncpromise';

packages/utils/src/node-stack-trace.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2222
// THE SOFTWARE.
2323

24-
import type { StackLineParserFn } from '@sentry/types';
24+
import type { StackLineParser, StackLineParserFn } from '@sentry/types';
25+
import { UNKNOWN_FUNCTION } from './stacktrace';
2526

2627
export type GetModuleFn = (filename: string | undefined) => string | undefined;
2728

@@ -96,7 +97,7 @@ export function node(getModule?: GetModuleFn): StackLineParserFn {
9697
}
9798

9899
if (functionName === undefined) {
99-
methodName = methodName || '<anonymous>';
100+
methodName = methodName || UNKNOWN_FUNCTION;
100101
functionName = typeName ? `${typeName}.${methodName}` : methodName;
101102
}
102103

@@ -131,3 +132,13 @@ export function node(getModule?: GetModuleFn): StackLineParserFn {
131132
return undefined;
132133
};
133134
}
135+
136+
/**
137+
* Node.js stack line parser
138+
*
139+
* This is in @sentry/utils so it can be used from the Electron SDK in the browser for when `nodeIntegration == true`.
140+
* This allows it to be used without referencing or importing any node specific code which causes bundlers to complain
141+
*/
142+
export function nodeStackLineParser(getModule?: GetModuleFn): StackLineParser {
143+
return [90, node(getModule)];
144+
}

packages/utils/src/stacktrace.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import type { StackFrame, StackLineParser, StackParser } from '@sentry/types';
22

3-
import type { GetModuleFn } from './node-stack-trace';
4-
import { filenameIsInApp, node } from './node-stack-trace';
5-
6-
export { filenameIsInApp };
7-
83
const STACKTRACE_FRAME_LIMIT = 50;
4+
export const UNKNOWN_FUNCTION = '?';
95
// Used to sanitize webpack (error: *) wrapped stack errors
106
const WEBPACK_ERROR_REGEXP = /\(error: (.*)\)/;
117
const STRIP_FRAME_REGEXP = /captureMessage|captureException/;
@@ -116,7 +112,7 @@ export function stripSentryFramesAndReverse(stack: ReadonlyArray<StackFrame>): S
116112
return localStack.slice(0, STACKTRACE_FRAME_LIMIT).map(frame => ({
117113
...frame,
118114
filename: frame.filename || localStack[localStack.length - 1].filename,
119-
function: frame.function || '?',
115+
function: frame.function || UNKNOWN_FUNCTION,
120116
}));
121117
}
122118

@@ -137,13 +133,3 @@ export function getFunctionName(fn: unknown): string {
137133
return defaultFunctionName;
138134
}
139135
}
140-
141-
/**
142-
* Node.js stack line parser
143-
*
144-
* This is in @sentry/utils so it can be used from the Electron SDK in the browser for when `nodeIntegration == true`.
145-
* This allows it to be used without referencing or importing any node specific code which causes bundlers to complain
146-
*/
147-
export function nodeStackLineParser(getModule?: GetModuleFn): StackLineParser {
148-
return [90, node(getModule)];
149-
}

packages/utils/test/stacktrace.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { nodeStackLineParser, stripSentryFramesAndReverse } from '../src/stacktrace';
1+
import { nodeStackLineParser, stripSentryFramesAndReverse } from '../src';
22

33
describe('Stacktrace', () => {
44
describe('stripSentryFramesAndReverse()', () => {
@@ -157,7 +157,7 @@ describe('node', () => {
157157
const expectedOutput = {
158158
filename: '/path/to/file.js',
159159
module: undefined,
160-
function: '<anonymous>',
160+
function: '?',
161161
lineno: 10,
162162
colno: 5,
163163
in_app: true,
@@ -257,7 +257,7 @@ describe('node', () => {
257257

258258
expect(result).toEqual({
259259
filename: '/path/to/myFile.js',
260-
function: 'Object.<anonymous>',
260+
function: 'Object.?',
261261
lineno: 10,
262262
colno: 20,
263263
in_app: true,
@@ -269,7 +269,7 @@ describe('node', () => {
269269
const result = node(line);
270270
expect(result).toEqual({
271271
filename: '/path/to/myFile.js',
272-
function: '<anonymous>',
272+
function: '?',
273273
lineno: 10,
274274
colno: 20,
275275
in_app: true,
@@ -281,7 +281,7 @@ describe('node', () => {
281281
const result = node(line);
282282
expect(result).toEqual({
283283
filename: undefined,
284-
function: 'Object.<anonymous>',
284+
function: 'Object.?',
285285
lineno: undefined,
286286
colno: undefined,
287287
in_app: false,
@@ -294,7 +294,7 @@ describe('node', () => {
294294

295295
expect(result).toEqual({
296296
filename: '/path/to/node_modules/myModule/index.js',
297-
function: 'Object.<anonymous>',
297+
function: 'Object.?',
298298
lineno: 10,
299299
colno: 20,
300300
in_app: false,
@@ -306,7 +306,7 @@ describe('node', () => {
306306
const result = node(line);
307307
expect(result).toEqual({
308308
filename: 'C:\\path\\to\\myFile.js',
309-
function: 'Object.<anonymous>',
309+
function: 'Object.?',
310310
lineno: 10,
311311
colno: 20,
312312
in_app: true,

0 commit comments

Comments
 (0)