@@ -8,6 +8,24 @@ import type { Handle, ResolveOptions } from '@sveltejs/kit';
8
8
import { isHttpError , isRedirect } from '../common/utils' ;
9
9
import { getTracePropagationData } from './utils' ;
10
10
11
+ export type SentryHandleOptions = {
12
+ /**
13
+ * Controls whether the SDK should capture errors and traces in requests that don't belong to a
14
+ * route defined in your SvelteKit application.
15
+ *
16
+ * By default, this option is set to `false` to reduce noise (e.g. bots sending random requests to your server).
17
+ *
18
+ * Set this option to `true` if you want to monitor requests events without a route. This might be useful in certain
19
+ * scenarios, for instance if you registered other handlers that handle these requests.
20
+ * If you set this option, you might want adjust the the transaction name in the `beforeSendTransaction`
21
+ * callback of your server-side `Sentry.init` options. You can also use `beforeSendTransaction` to filter out
22
+ * transactions that you still don't want to be sent to Sentry.
23
+ *
24
+ * @default false
25
+ */
26
+ handleUnknownRoutes ?: boolean ;
27
+ } ;
28
+
11
29
function sendErrorToSentry ( e : unknown ) : unknown {
12
30
// In case we have a primitive, wrap it in the equivalent wrapper class (string -> String, etc.) so that we can
13
31
// store a seen flag on it.
@@ -68,33 +86,42 @@ export const transformPageChunk: NonNullable<ResolveOptions['transformPageChunk'
68
86
* // export const handle = sequence(sentryHandle(), yourCustomHandler);
69
87
* ```
70
88
*/
71
- export function sentryHandle ( ) : Handle {
89
+ export function sentryHandle ( handlerOptions ?: SentryHandleOptions ) : Handle {
90
+ const options = {
91
+ handleUnknownRoutes : false ,
92
+ ...handlerOptions ,
93
+ } ;
94
+
95
+ const sentryRequestHandler : Handle = input => {
96
+ // if there is an active transaction, we know that this handle call is nested and hence
97
+ // we don't create a new domain for it. If we created one, nested server calls would
98
+ // create new transactions instead of adding a child span to the currently active span.
99
+ if ( getCurrentHub ( ) . getScope ( ) . getSpan ( ) ) {
100
+ return instrumentHandle ( input , options ) ;
101
+ }
102
+ return runWithAsyncContext ( ( ) => {
103
+ return instrumentHandle ( input , options ) ;
104
+ } ) ;
105
+ } ;
106
+
72
107
return sentryRequestHandler ;
73
108
}
74
109
75
- const sentryRequestHandler : Handle = input => {
76
- // if there is an active transaction, we know that this handle call is nested and hence
77
- // we don't create a new domain for it. If we created one, nested server calls would
78
- // create new transactions instead of adding a child span to the currently active span.
79
- if ( getCurrentHub ( ) . getScope ( ) . getSpan ( ) ) {
80
- return instrumentHandle ( input ) ;
110
+ function instrumentHandle ( { event, resolve } : Parameters < Handle > [ 0 ] , options : SentryHandleOptions ) : ReturnType < Handle > {
111
+ if ( ! event . route ?. id && ! options . handleUnknownRoutes ) {
112
+ return resolve ( event ) ;
81
113
}
82
- return runWithAsyncContext ( ( ) => {
83
- return instrumentHandle ( input ) ;
84
- } ) ;
85
- } ;
86
114
87
- function instrumentHandle ( { event, resolve } : Parameters < Handle > [ 0 ] ) : ReturnType < Handle > {
88
115
const { traceparentData, dynamicSamplingContext } = getTracePropagationData ( event ) ;
89
116
90
117
return trace (
91
118
{
92
119
op : 'http.server' ,
93
- name : `${ event . request . method } ${ event . route . id } ` ,
120
+ name : `${ event . request . method } ${ event . route ? .id || event . url . pathname } ` ,
94
121
status : 'ok' ,
95
122
...traceparentData ,
96
123
metadata : {
97
- source : 'route' ,
124
+ source : event . route ?. id ? 'route' : 'url ',
98
125
dynamicSamplingContext : traceparentData && ! dynamicSamplingContext ? { } : dynamicSamplingContext ,
99
126
} ,
100
127
} ,
0 commit comments