diff --git a/dev-packages/e2e-tests/test-applications/sveltekit-2-svelte-5/test/errors.server.test.ts b/dev-packages/e2e-tests/test-applications/sveltekit-2-svelte-5/test/errors.server.test.ts index f169b0bf6b68..bbd87a5366a6 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit-2-svelte-5/test/errors.server.test.ts +++ b/dev-packages/e2e-tests/test-applications/sveltekit-2-svelte-5/test/errors.server.test.ts @@ -20,6 +20,16 @@ test.describe('server-side errors', () => { ); expect(errorEvent.tags).toMatchObject({ runtime: 'node' }); + + expect(errorEvent.request).toEqual({ + cookies: {}, + headers: expect.objectContaining({ + accept: expect.any(String), + 'user-agent': expect.any(String), + }), + method: 'GET', + url: 'http://localhost:3030/universal-load-error', + }); }); test('captures server load error', async ({ page }) => { @@ -40,6 +50,16 @@ test.describe('server-side errors', () => { ); expect(errorEvent.tags).toMatchObject({ runtime: 'node' }); + + expect(errorEvent.request).toEqual({ + cookies: {}, + headers: expect.objectContaining({ + accept: expect.any(String), + 'user-agent': expect.any(String), + }), + method: 'GET', + url: 'http://localhost:3030/server-load-error', + }); }); test('captures server route (GET) error', async ({ page }) => { @@ -61,5 +81,14 @@ test.describe('server-side errors', () => { ); expect(errorEvent.transaction).toEqual('GET /server-route-error'); + + expect(errorEvent.request).toEqual({ + cookies: {}, + headers: expect.objectContaining({ + accept: expect.any(String), + }), + method: 'GET', + url: 'http://localhost:3030/server-route-error', + }); }); }); diff --git a/dev-packages/e2e-tests/test-applications/sveltekit-2-svelte-5/test/performance.server.test.ts b/dev-packages/e2e-tests/test-applications/sveltekit-2-svelte-5/test/performance.server.test.ts index d43941f2a0c2..10d0690e70b8 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit-2-svelte-5/test/performance.server.test.ts +++ b/dev-packages/e2e-tests/test-applications/sveltekit-2-svelte-5/test/performance.server.test.ts @@ -32,4 +32,14 @@ test('server pageload request span has nested request span for sub request', asy expect.objectContaining({ op: 'http.server', description: 'GET /api/users' }), ]), ); + + expect(serverTxnEvent.request).toEqual({ + cookies: {}, + headers: expect.objectContaining({ + accept: expect.any(String), + 'user-agent': expect.any(String), + }), + method: 'GET', + url: 'http://localhost:3030/server-load-fetch', + }); }); diff --git a/dev-packages/e2e-tests/test-applications/sveltekit/test/errors.server.test.ts b/dev-packages/e2e-tests/test-applications/sveltekit/test/errors.server.test.ts index d2215cf8e763..5a3940a213b5 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit/test/errors.server.test.ts +++ b/dev-packages/e2e-tests/test-applications/sveltekit/test/errors.server.test.ts @@ -21,6 +21,16 @@ test.describe('server-side errors', () => { ); expect(errorEvent.tags).toMatchObject({ runtime: 'node' }); + + expect(errorEvent.request).toEqual({ + cookies: {}, + headers: expect.objectContaining({ + accept: expect.any(String), + 'user-agent': expect.any(String), + }), + method: 'GET', + url: 'http://localhost:3030/universal-load-error', + }); }); test('captures server load error', async ({ page }) => { @@ -42,6 +52,16 @@ test.describe('server-side errors', () => { ); expect(errorEvent.tags).toMatchObject({ runtime: 'node' }); + + expect(errorEvent.request).toEqual({ + cookies: {}, + headers: expect.objectContaining({ + accept: expect.any(String), + 'user-agent': expect.any(String), + }), + method: 'GET', + url: 'http://localhost:3030/server-load-error', + }); }); test('captures server route (GET) error', async ({ page }) => { @@ -64,5 +84,14 @@ test.describe('server-side errors', () => { ); expect(errorEvent.transaction).toEqual('GET /server-route-error'); + + expect(errorEvent.request).toEqual({ + cookies: {}, + headers: expect.objectContaining({ + accept: expect.any(String), + }), + method: 'GET', + url: 'http://localhost:3030/server-route-error', + }); }); }); diff --git a/dev-packages/e2e-tests/test-applications/sveltekit/test/performance.server.test.ts b/dev-packages/e2e-tests/test-applications/sveltekit/test/performance.server.test.ts index a363d28f291b..e462d08ddeeb 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit/test/performance.server.test.ts +++ b/dev-packages/e2e-tests/test-applications/sveltekit/test/performance.server.test.ts @@ -32,4 +32,14 @@ test('server pageload request span has nested request span for sub request', asy expect.objectContaining({ op: 'http.server', description: 'GET /api/users' }), ]), ); + + expect(serverTxnEvent.request).toEqual({ + cookies: {}, + headers: expect.objectContaining({ + accept: expect.any(String), + 'user-agent': expect.any(String), + }), + method: 'GET', + url: 'http://localhost:3030/server-load-fetch', + }); }); diff --git a/packages/sveltekit/src/server/handle.ts b/packages/sveltekit/src/server/handle.ts index ee55ed810e8e..56ddc23e1885 100644 --- a/packages/sveltekit/src/server/handle.ts +++ b/packages/sveltekit/src/server/handle.ts @@ -2,6 +2,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, getActiveSpan, + getCurrentScope, getDefaultIsolationScope, getIsolationScope, getRootSpan, @@ -12,7 +13,12 @@ import { import { startSpan } from '@sentry/core'; import { captureException, continueTrace } from '@sentry/node'; import type { Span } from '@sentry/types'; -import { dynamicSamplingContextToSentryBaggageHeader, logger, objectify } from '@sentry/utils'; +import { + dynamicSamplingContextToSentryBaggageHeader, + logger, + objectify, + winterCGRequestToRequestData, +} from '@sentry/utils'; import type { Handle, ResolveOptions } from '@sveltejs/kit'; import { getDynamicSamplingContextFromSpan } from '@sentry/opentelemetry'; @@ -168,9 +174,10 @@ export function sentryHandle(handlerOptions?: SentryHandleOptions): Handle { return instrumentHandle(input, options); } - return withIsolationScope(() => { + return withIsolationScope(isolationScope => { // We only call continueTrace in the initial top level request to avoid // creating a new root span for the sub request. + isolationScope.setSDKProcessingMetadata({ request: winterCGRequestToRequestData(input.event.request.clone()) }); return continueTrace(getTracePropagationData(input.event), () => instrumentHandle(input, options)); }); }; @@ -206,6 +213,7 @@ async function instrumentHandle( name: routeName, }, async (span?: Span) => { + getCurrentScope().setSDKProcessingMetadata({ request: winterCGRequestToRequestData(event.request.clone()) }); const res = await resolve(event, { transformPageChunk: addSentryCodeToPage(options), }); diff --git a/packages/sveltekit/test/server/handle.test.ts b/packages/sveltekit/test/server/handle.test.ts index e029a118b411..e34f507af047 100644 --- a/packages/sveltekit/test/server/handle.test.ts +++ b/packages/sveltekit/test/server/handle.test.ts @@ -44,6 +44,8 @@ function mockEvent(override: Record = {}): Parameters[0 ...override, }; + event.request.clone = () => event.request; + return event; }