diff --git a/dev-packages/node-integration-tests/suites/public-api/LocalVariables/local-variables-name-matching.js b/dev-packages/node-integration-tests/suites/public-api/LocalVariables/local-variables-name-matching.js new file mode 100644 index 000000000000..b9027b749181 --- /dev/null +++ b/dev-packages/node-integration-tests/suites/public-api/LocalVariables/local-variables-name-matching.js @@ -0,0 +1,35 @@ +const Sentry = require('@sentry/node'); +const { loggingTransport } = require('@sentry-internal/node-integration-tests'); + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + includeLocalVariables: true, + transport: loggingTransport, +}); + +process.on('uncaughtException', () => { + // do nothing - this will prevent the Error below from closing this process +}); + +// Testing GraphQL resolver: https://github.com/getsentry/sentry-javascript/issues/16701 +const resolvers = { + Query: { + testSentry: args => { + try { + args.foo.map(x => x); + return true; + } catch (error) { + Sentry.captureException(error); + return false; + } + }, + }, +}; + +function regularFunction() { + resolvers.Query.testSentry({ foo: undefined }); +} + +setTimeout(() => { + regularFunction(); +}, 1000); diff --git a/dev-packages/node-integration-tests/suites/public-api/LocalVariables/test.ts b/dev-packages/node-integration-tests/suites/public-api/LocalVariables/test.ts index e95e5a9e3767..2c87d14c2b45 100644 --- a/dev-packages/node-integration-tests/suites/public-api/LocalVariables/test.ts +++ b/dev-packages/node-integration-tests/suites/public-api/LocalVariables/test.ts @@ -101,4 +101,30 @@ describe('LocalVariables integration', () => { .start() .completed(); }); + + test('Should handle different function name formats', async () => { + await createRunner(__dirname, 'local-variables-name-matching.js') + .expect({ + event: { + exception: { + values: [ + { + stacktrace: { + frames: expect.arrayContaining([ + expect.objectContaining({ + function: expect.stringMatching(/^(Object\.testSentry|testSentry)$/), + vars: expect.objectContaining({ + args: expect.any(Object), + }), + }), + ]), + }, + }, + ], + }, + }, + }) + .start() + .completed(); + }); }); diff --git a/packages/node/src/integrations/local-variables/common.ts b/packages/node/src/integrations/local-variables/common.ts index 58ccea70d6de..471fa1a69864 100644 --- a/packages/node/src/integrations/local-variables/common.ts +++ b/packages/node/src/integrations/local-variables/common.ts @@ -70,7 +70,7 @@ export function isAnonymous(name: string | undefined): boolean { /** Do the function names appear to match? */ export function functionNamesMatch(a: string | undefined, b: string | undefined): boolean { - return a === b || (isAnonymous(a) && isAnonymous(b)); + return a === b || `Object.${a}` === b || a === `Object.${b}` || (isAnonymous(a) && isAnonymous(b)); } export interface FrameVariables {