diff --git a/packages/sveltekit/src/server/load.ts b/packages/sveltekit/src/server/load.ts index 0ad28e1cb4eb..04d0137062c6 100644 --- a/packages/sveltekit/src/server/load.ts +++ b/packages/sveltekit/src/server/load.ts @@ -119,7 +119,11 @@ export function wrapServerLoadWithSentry any>(origSe addNonEnumerableProperty(event as unknown as Record, '__sentry_wrapped__', true); - const routeId = event.route && event.route.id; + // Accessing any member of `event.route` causes SvelteKit to invalidate the + // server `load` function's data on every route change. + // To work around this, we use `Object.getOwnPropertyDescriptor` which doesn't invoke the proxy. + // https://github.com/sveltejs/kit/blob/e133aba479fa9ba0e7f9e71512f5f937f0247e2c/packages/kit/src/runtime/server/page/load_data.js#L111C3-L124 + const routeId = event.route && (Object.getOwnPropertyDescriptor(event.route, 'id')?.value as string | undefined); const { dynamicSamplingContext, traceparentData, propagationContext } = getTracePropagationData(event); getCurrentHub().getScope().setPropagationContext(propagationContext); diff --git a/packages/sveltekit/test/server/load.test.ts b/packages/sveltekit/test/server/load.test.ts index fa57dc6b7c46..90980204cf68 100644 --- a/packages/sveltekit/test/server/load.test.ts +++ b/packages/sveltekit/test/server/load.test.ts @@ -400,4 +400,33 @@ describe('wrapServerLoadWithSentry calls trace', () => { expect(mockTrace).toHaveBeenCalledTimes(1); }); + + it("doesn't invoke the proxy set on `event.route`", async () => { + const event = getServerOnlyArgs(); + + // simulates SvelteKit adding a proxy to `event.route` + // https://github.com/sveltejs/kit/blob/e133aba479fa9ba0e7f9e71512f5f937f0247e2c/packages/kit/src/runtime/server/page/load_data.js#L111C3-L124 + const proxyFn = vi.fn((target: { id: string }, key: string | symbol): any => { + return target[key]; + }); + + event.route = new Proxy(event.route, { + get: proxyFn, + }); + + const wrappedLoad = wrapServerLoadWithSentry(serverLoad); + await wrappedLoad(event); + + expect(mockTrace).toHaveBeenCalledTimes(1); + expect(mockTrace).toHaveBeenCalledWith( + expect.objectContaining({ + op: 'function.sveltekit.server.load', + name: '/users/[id]', // <-- this shows that the route was still accessed + }), + expect.any(Function), + expect.any(Function), + ); + + expect(proxyFn).not.toHaveBeenCalled(); + }); });