Skip to content

Commit 06be094

Browse files
committed
feat(sveltekit): Add wrapper for remote function invokation
1 parent 6d451e9 commit 06be094

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { addNonEnumerableProperty, captureException, flushIfServerless, startSpan } from '@sentry/core';
2+
import type { LoadEvent } from '@sveltejs/kit';
3+
import type { SentryWrappedFlag } from '../common/utils';
4+
5+
type PatchedRequestEvent = LoadEvent & SentryWrappedFlag;
6+
7+
/**
8+
* Wraps a remote function invokation with a Sentry span and captures an exception if the remote function throws.
9+
*/
10+
export function wrapRemoteFunctionWithSentry<T extends (...args: any) => any>(origRemoteFn: T): T {
11+
return new Proxy(origRemoteFn, {
12+
apply: async (wrappingTarget, thisArg, args: Parameters<T>) => {
13+
// Type casting here because `T` cannot extend `Load` (see comment above function signature)
14+
// Also, this event possibly already has a sentry wrapped flag attached
15+
const event = args[0] as PatchedRequestEvent;
16+
17+
if (event.__sentry_wrapped__) {
18+
return wrappingTarget.apply(thisArg, args);
19+
}
20+
21+
addNonEnumerableProperty(event as unknown as Record<string, unknown>, '__sentry_wrapped__', true);
22+
23+
const routeId = event.route?.id;
24+
25+
try {
26+
// We need to await before returning, otherwise we won't catch any errors thrown by the load function
27+
return await startSpan(
28+
{
29+
name: routeId ? routeId : event.url.pathname,
30+
},
31+
() => wrappingTarget.apply(thisArg, args),
32+
);
33+
} catch (e) {
34+
captureException(e);
35+
throw e;
36+
} finally {
37+
await flushIfServerless();
38+
}
39+
},
40+
});
41+
}

0 commit comments

Comments
 (0)