From c35607308eefe0fac0b99bf95eba1734ef0eeb5a Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Mon, 2 Oct 2023 11:58:54 +0200 Subject: [PATCH] fix(sveltekit): Avoid data invalidation in wrapped client-side `load` functions (#9071) This patch fixes a data invalidation issue that appeared on the client side when auto-instrumenting or manually wrapping universal `load` functions. Because our `wrapLoadWithSentry` function accessed `event.route.id`, the data returned from `load` would be invalidated on a route change. As reported in #8818 , this caused prefetched, actually still valid data to be invalidated during the navigation to the page, causing another `load` invocation. To avoid this invalidation, we change the way how we read the route.id, to first use `Object.getOwnPropertyDescriptor` which doesn't trigger the proxy that listens to accesses. This, however, will only work for `@sveltejs/kit>=1.24.0` which includes a [change](https://github.com/sveltejs/kit/pull/10576) to the Kit-internal proxy. For older versions of kit, we continue to directly read from `event.route.id`, which will still cause invalidations. Not ideal but IMO the best we can do without loosing data. closes #8818 --- packages/sveltekit/src/client/load.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/sveltekit/src/client/load.ts b/packages/sveltekit/src/client/load.ts index 673941d76488..93d835dd72d1 100644 --- a/packages/sveltekit/src/client/load.ts +++ b/packages/sveltekit/src/client/load.ts @@ -71,7 +71,17 @@ export function wrapLoadWithSentry any>(origLoad: T) addNonEnumerableProperty(patchedEvent as unknown as Record, '__sentry_wrapped__', true); - const routeId = event.route.id; + // Accessing any member of `event.route` causes SvelteKit to invalidate the + // client-side universal `load` function's data prefetched data, causing another reload on the actual navigation. + // To work around this, we use `Object.getOwnPropertyDescriptor` which doesn't invoke the proxy. + const routeIdDescriptor = event.route && Object.getOwnPropertyDescriptor(event.route, 'id'); + // First, we try to access the route id from the property descriptor. + // This will only work for @sveltejs/kit >= 1.24.0 + const routeIdFromDescriptor = routeIdDescriptor && (routeIdDescriptor.value as string | undefined); + // If routeIdFromDescriptor is undefined, we fall back to the old behavior of accessing + // `event.route.id` directly. This will still cause invalidations but we get a route name. + const routeId = routeIdFromDescriptor || event.route.id; + return trace( { op: 'function.sveltekit.load',