From 9ccb8c858abc274bf9a33a427ecffddbc3ddd03d Mon Sep 17 00:00:00 2001 From: Martin Sonnberger Date: Mon, 7 Sep 2026 10:36:53 +0200 Subject: [PATCH] refactor(core): Remove beforeSendSpan null return warning Co-Authored-By: GPT-6 --- .../core/src/tracing/spans/beforeSendSpan.ts | 17 +------ packages/core/test/lib/client.test.ts | 45 ------------------- .../lib/tracing/spans/captureSpan.test.ts | 20 ++++----- 3 files changed, 11 insertions(+), 71 deletions(-) diff --git a/packages/core/src/tracing/spans/beforeSendSpan.ts b/packages/core/src/tracing/spans/beforeSendSpan.ts index b2fcd8261079..4acc765f19b2 100644 --- a/packages/core/src/tracing/spans/beforeSendSpan.ts +++ b/packages/core/src/tracing/spans/beforeSendSpan.ts @@ -2,7 +2,6 @@ import { DEBUG_BUILD } from '../../debug-build'; import type { BeforeSendStaticSpanCallback, BeforeSendStreamedSpanCallback } from '../../types/options'; import type { SpanJSON, StreamedSpanJSON } from '../../types/span'; import { addNonEnumerableProperty } from '../../utils/object'; -import { consoleSandbox } from '../../utils/debug-logger'; import { safeCallback } from '../../utils/safeCallback'; /** @@ -57,7 +56,6 @@ export function isStaticBeforeSendSpanCallback(callback: unknown): callback is B return !!callback && typeof callback === 'function' && '_static' in callback && !!callback._static; } -let hasShownSpanDropWarning = false; /** * Apply a user-provided beforeSendSpan callback to a span JSON. */ @@ -72,18 +70,5 @@ export function applyBeforeSendSpanCallback beforeSendSpan(span), () => span, ); - if (modifiedSpan) { - return modifiedSpan; - } - - if (!hasShownSpanDropWarning) { - consoleSandbox(() => { - // eslint-disable-next-line no-console - console.warn( - '[Sentry] Returning null from `beforeSendSpan` is disallowed. To drop certain spans, configure the respective integrations directly or use `ignoreSpans`.', - ); - }); - hasShownSpanDropWarning = true; - } - return span; + return modifiedSpan || span; } diff --git a/packages/core/test/lib/client.test.ts b/packages/core/test/lib/client.test.ts index e2c3269c4929..c77bdce7d24c 100644 --- a/packages/core/test/lib/client.test.ts +++ b/packages/core/test/lib/client.test.ts @@ -1711,51 +1711,6 @@ describe('Client', () => { expect(loggerLogSpy).toBeCalledWith('before send for type `transaction` returned `null`, will not send event.'); }); - test('does not discard span and warn when returning null from `beforeSendSpan', () => { - const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => undefined); - - // @ts-expect-error - intentionally violating the type signature here - const beforeSendSpan = withStaticSpan(vi.fn(() => null)); - - const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, beforeSendSpan }); - const client = new TestClient(options); - - const transaction: Event = { - transaction: '/dogs/are/great', - type: 'transaction', - spans: [ - { - description: 'first span', - span_id: '9e15bf99fbe4bc80', - start_timestamp: 1591603196.637835, - trace_id: '86f39e84263a4de99c326acab3bfe3bd', - data: {}, - status: 'ok', - }, - { - description: 'second span', - span_id: 'aa554c1f506b0783', - start_timestamp: 1591603196.637835, - trace_id: '86f39e84263a4de99c326acab3bfe3bd', - data: {}, - status: 'ok', - }, - ], - }; - client.captureEvent(transaction); - - expect(beforeSendSpan).toHaveBeenCalledTimes(3); - const capturedEvent = TestClient.instance!.event!; - expect(capturedEvent.spans).toHaveLength(2); - expect(client['_outcomes']).toEqual({}); - - expect(consoleWarnSpy).toHaveBeenCalledTimes(1); - expect(consoleWarnSpy).toHaveBeenCalledWith( - '[Sentry] Returning null from `beforeSendSpan` is disallowed. To drop certain spans, configure the respective integrations directly or use `ignoreSpans`.', - ); - consoleWarnSpy.mockRestore(); - }); - test("doesn't throw if the `beforeSendSpan` callback throws", () => { const debugErrorSpy = vi.spyOn(debugLoggerModule.debug, 'error').mockImplementation(() => undefined); const error = new Error('beforeSendSpan is broken'); diff --git a/packages/core/test/lib/tracing/spans/captureSpan.test.ts b/packages/core/test/lib/tracing/spans/captureSpan.test.ts index 24a45b0eb561..6035b3ee97b9 100644 --- a/packages/core/test/lib/tracing/spans/captureSpan.test.ts +++ b/packages/core/test/lib/tracing/spans/captureSpan.test.ts @@ -507,8 +507,7 @@ describe('captureSpan', () => { expect(beforeSendSpan).not.toHaveBeenCalled(); }); - it('logs a warning if the beforeSendSpan callback returns null', () => { - const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => undefined); + it('keeps the span if the beforeSendSpan callback returns null', () => { const beforeSendSpan = vi.fn(() => null as unknown as StreamedSpanJSON); const client = new TestClient( @@ -522,16 +521,17 @@ describe('captureSpan', () => { }), ); - const span = startInactiveSpan({ name: 'my-span', attributes: { 'sentry.op': 'http.client' } }); - span.end(); - - captureSpan(span, client); + const span = withScope(scope => { + scope.setClient(client); + const span = startInactiveSpan({ name: 'my-span', attributes: { 'sentry.op': 'http.client' } }); + span.end(); + return span; + }); - expect(consoleWarnSpy).toHaveBeenCalledWith( - '[Sentry] Returning null from `beforeSendSpan` is disallowed. To drop certain spans, configure the respective integrations directly or use `ignoreSpans`.', - ); + const serialized = captureSpan(span, client); - consoleWarnSpy.mockRestore(); + expect(serialized.span_id).toBe(span.spanContext().spanId); + expect(serialized.name).toBe('my-span'); }); it('keeps the span and logs an error if the beforeSendSpan callback throws', () => {