1
1
import { captureException } from '@sentry/node' ;
2
- import type { HandleServerError , RequestEvent } from '@sveltejs/kit' ;
2
+ import type { HandleServerError } from '@sveltejs/kit' ;
3
3
4
4
import { flushIfServerless } from './utils' ;
5
5
@@ -11,14 +11,28 @@ function defaultErrorHandler({ error }: Parameters<HandleServerError>[0]): Retur
11
11
console . error ( error && error . stack ) ;
12
12
}
13
13
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
+
14
26
/**
15
27
* Wrapper for the SvelteKit error handler that sends the error to Sentry.
16
28
*
17
29
* @param handleError The original SvelteKit error handler.
18
30
*/
19
31
export 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 > => {
21
33
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
22
36
return handleError ( input ) ;
23
37
}
24
38
@@ -31,6 +45,8 @@ export function handleErrorWithSentry(handleError: HandleServerError = defaultEr
31
45
32
46
await flushIfServerless ( ) ;
33
47
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
34
50
return handleError ( input ) ;
35
51
} ;
36
52
}
@@ -41,9 +57,17 @@ export function handleErrorWithSentry(handleError: HandleServerError = defaultEr
41
57
* so we have to check if the error is a "Not found" error by checking if the route id is missing and
42
58
* by checking the error message on top of the raw stack trace.
43
59
*/
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
+ }
46
67
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
47
71
const hasNoRouteId = ! event . route || ! event . route . id ;
48
72
49
73
const rawStack : string =
0 commit comments