11import { captureException } from '@sentry/node' ;
2- import type { HandleServerError , RequestEvent } from '@sveltejs/kit' ;
2+ import type { HandleServerError } from '@sveltejs/kit' ;
33
44import { flushIfServerless } from './utils' ;
55
@@ -11,14 +11,28 @@ function defaultErrorHandler({ error }: Parameters<HandleServerError>[0]): Retur
1111 console . error ( error && error . stack ) ;
1212}
1313
14+ type HandleServerErrorInput = Parameters < HandleServerError > [ 0 ] ;
15+
16+ /**
17+ * Backwards-compatible HandleServerError Input type for SvelteKit 1.x and 2.x
18+ * `message` and `status` were added in 2.x.
19+ * For backwards-compatibility, we make them optional
20+ *
21+ * @see https://kit.svelte.dev/docs/migrating-to-sveltekit-2#improved-error-handling
22+ */
23+ type SafeHandleServerErrorInput = Omit < HandleServerErrorInput , 'status' | 'message' > &
24+ Partial < Pick < HandleServerErrorInput , 'status' | 'message' > > ;
25+
1426/**
1527 * Wrapper for the SvelteKit error handler that sends the error to Sentry.
1628 *
1729 * @param handleError The original SvelteKit error handler.
1830 */
1931export function handleErrorWithSentry ( handleError : HandleServerError = defaultErrorHandler ) : HandleServerError {
20- return async ( input : { error : unknown ; event : RequestEvent } ) : Promise < void | App . Error > => {
32+ return async ( input : SafeHandleServerErrorInput ) : Promise < void | App . Error > => {
2133 if ( isNotFoundError ( input ) ) {
34+ // We're extra cautious with SafeHandleServerErrorInput - this type is not compatible with HandleServerErrorInput
35+ // @ts -expect-error - we're still passing the same object, just with a different (backwards-compatible) type
2236 return handleError ( input ) ;
2337 }
2438
@@ -31,6 +45,8 @@ export function handleErrorWithSentry(handleError: HandleServerError = defaultEr
3145
3246 await flushIfServerless ( ) ;
3347
48+ // We're extra cautious with SafeHandleServerErrorInput - this type is not compatible with HandleServerErrorInput
49+ // @ts -expect-error - we're still passing the same object, just with a different (backwards-compatible) type
3450 return handleError ( input ) ;
3551 } ;
3652}
@@ -41,9 +57,17 @@ export function handleErrorWithSentry(handleError: HandleServerError = defaultEr
4157 * so we have to check if the error is a "Not found" error by checking if the route id is missing and
4258 * by checking the error message on top of the raw stack trace.
4359 */
44- function isNotFoundError ( input : { error : unknown ; event : RequestEvent } ) : boolean {
45- const { error, event } = input ;
60+ function isNotFoundError ( input : SafeHandleServerErrorInput ) : boolean {
61+ const { error, event, status, message } = input ;
62+
63+ // SvelteKit 2.0 offers a reliable way to check for a Not Found error:
64+ if ( status === 404 && message === 'Not Found' ) {
65+ return true ;
66+ }
4667
68+ // SvelteKit 1.x doesn't offer a reliable way to check for a Not Found error.
69+ // So we check the route id (shouldn't exist) and the raw stack trace
70+ // We can delete all of this below whenever we drop Kit 1.x support
4771 const hasNoRouteId = ! event . route || ! event . route . id ;
4872
4973 const rawStack : string =
0 commit comments