From cdaf8522582a72fae4aacc19005f31fab910fed7 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 12 Dec 2024 19:29:44 +0100 Subject: [PATCH] fix(core): Mark stack trace from `captureMessage` with `attatchStackTrace: true` as synthetic (#14670) Analogously to #14668 for browser, this patch marks synthetic exceptions captured during a `captureException()` call as synthetic. --- .../scenario.ts | 11 ++++ .../simple_message_attachStackTrace/test.ts | 25 ++++++++ packages/core/src/utils-hoist/eventbuilder.ts | 1 + .../test/utils-hoist/eventbuilder.test.ts | 62 ++++++++++++++++++- 4 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 dev-packages/node-integration-tests/suites/public-api/captureMessage/simple_message_attachStackTrace/scenario.ts create mode 100644 dev-packages/node-integration-tests/suites/public-api/captureMessage/simple_message_attachStackTrace/test.ts diff --git a/dev-packages/node-integration-tests/suites/public-api/captureMessage/simple_message_attachStackTrace/scenario.ts b/dev-packages/node-integration-tests/suites/public-api/captureMessage/simple_message_attachStackTrace/scenario.ts new file mode 100644 index 000000000000..b56cb5cae8e6 --- /dev/null +++ b/dev-packages/node-integration-tests/suites/public-api/captureMessage/simple_message_attachStackTrace/scenario.ts @@ -0,0 +1,11 @@ +import { loggingTransport } from '@sentry-internal/node-integration-tests'; +import * as Sentry from '@sentry/node'; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + release: '1.0', + transport: loggingTransport, + attachStacktrace: true, +}); + +Sentry.captureMessage('Message'); diff --git a/dev-packages/node-integration-tests/suites/public-api/captureMessage/simple_message_attachStackTrace/test.ts b/dev-packages/node-integration-tests/suites/public-api/captureMessage/simple_message_attachStackTrace/test.ts new file mode 100644 index 000000000000..85b29fbcc239 --- /dev/null +++ b/dev-packages/node-integration-tests/suites/public-api/captureMessage/simple_message_attachStackTrace/test.ts @@ -0,0 +1,25 @@ +import { cleanupChildProcesses, createRunner } from '../../../../utils/runner'; + +afterAll(() => { + cleanupChildProcesses(); +}); + +test('capture a simple message string with a stack trace if `attachStackTrace` is `true`', done => { + createRunner(__dirname, 'scenario.ts') + .expect({ + event: { + message: 'Message', + level: 'info', + exception: { + values: [ + { + mechanism: { synthetic: true, type: 'generic', handled: true }, + value: 'Message', + stacktrace: { frames: expect.any(Array) }, + }, + ], + }, + }, + }) + .start(done); +}); diff --git a/packages/core/src/utils-hoist/eventbuilder.ts b/packages/core/src/utils-hoist/eventbuilder.ts index 42d23927f081..84d6e722ad7b 100644 --- a/packages/core/src/utils-hoist/eventbuilder.ts +++ b/packages/core/src/utils-hoist/eventbuilder.ts @@ -193,6 +193,7 @@ export function eventFromMessage( }, ], }; + addExceptionMechanism(event, { synthetic: true }); } } diff --git a/packages/core/test/utils-hoist/eventbuilder.test.ts b/packages/core/test/utils-hoist/eventbuilder.test.ts index afc193a343e3..2aea3b6192d9 100644 --- a/packages/core/test/utils-hoist/eventbuilder.test.ts +++ b/packages/core/test/utils-hoist/eventbuilder.test.ts @@ -1,5 +1,5 @@ import type { Client } from '../../src/types-hoist'; -import { eventFromUnknownInput } from '../../src/utils-hoist/eventbuilder'; +import { eventFromMessage, eventFromUnknownInput } from '../../src/utils-hoist/eventbuilder'; import { nodeStackLineParser } from '../../src/utils-hoist/node-stack-trace'; import { createStackParser } from '../../src/utils-hoist/stacktrace'; @@ -154,3 +154,63 @@ describe('eventFromUnknownInput', () => { expect(event.exception?.values?.[0]?.value).toBe('Object captured as exception with keys: foo, prop'); }); }); + +describe('eventFromMessage', () => { + it('creates an event from a string message', () => { + const event = eventFromMessage(stackParser, 'Test Message'); + expect(event).toEqual({ + event_id: undefined, // this is undefined because the hint isn't passed + level: 'info', + message: 'Test Message', + }); + }); + + it('attaches a synthetic exception if passed and `attachStackTrace` is true', () => { + const syntheticException = new Error('Test Message'); + const event = eventFromMessage( + stackParser, + 'Test Message', + 'info', + { syntheticException, event_id: '123abc' }, + true, + ); + + expect(event).toEqual({ + event_id: '123abc', + exception: { + values: [ + { + mechanism: { + handled: true, + synthetic: true, + type: 'generic', + }, + stacktrace: { + frames: expect.any(Array), + }, + value: 'Test Message', + }, + ], + }, + level: 'info', + message: 'Test Message', + }); + }); + + it("doesn't attach a synthetic exception if `attachStackTrace` is false", () => { + const syntheticException = new Error('Test Message'); + const event = eventFromMessage( + stackParser, + 'Test Message', + 'info', + { syntheticException, event_id: '123abc' }, + false, + ); + + expect(event).toEqual({ + event_id: '123abc', + level: 'info', + message: 'Test Message', + }); + }); +});