@@ -89,10 +89,18 @@ export function isFetchProxyRequired(version: string): boolean {
89
89
}
90
90
91
91
async function instrumentHandle (
92
- { event, resolve } : Parameters < Handle > [ 0 ] ,
93
- options : SentryHandleOptions ,
92
+ {
93
+ event,
94
+ resolve,
95
+ } : {
96
+ event : Parameters < Handle > [ 0 ] [ 'event' ] ;
97
+ resolve : Parameters < Handle > [ 0 ] [ 'resolve' ] ;
98
+ } ,
99
+ options : SentryHandleOptions & { svelteKitTracingEnabled : boolean } ,
94
100
) : Promise < Response > {
95
- if ( ! event . route ?. id && ! options . handleUnknownRoutes ) {
101
+ const routeId = event . route ?. id ;
102
+
103
+ if ( ! routeId && ! options . handleUnknownRoutes ) {
96
104
return resolve ( event ) ;
97
105
}
98
106
@@ -108,42 +116,53 @@ async function instrumentHandle(
108
116
}
109
117
}
110
118
111
- const routeName = `${ event . request . method } ${ event . route ?. id || event . url . pathname } ` ;
119
+ const routeName = `${ event . request . method } ${ routeId || event . url . pathname } ` ;
112
120
113
121
if ( getIsolationScope ( ) !== getDefaultIsolationScope ( ) ) {
114
122
getIsolationScope ( ) . setTransactionName ( routeName ) ;
115
123
} else {
116
124
DEBUG_BUILD && debug . warn ( 'Isolation scope is default isolation scope - skipping setting transactionName' ) ;
117
125
}
118
126
127
+ // We only start a span if SvelteKit's native tracing is not enabled. Two reasons:
128
+ // - Used Kit version doesn't yet support tracing
129
+ // - Users didn't enable tracing
130
+ const shouldStartSpan = ! options . svelteKitTracingEnabled ;
131
+
119
132
try {
120
- const resolveResult = await startSpan (
121
- {
122
- op : 'http.server' ,
123
- attributes : {
124
- [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.http.sveltekit' ,
125
- [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : event . route ?. id ? 'route' : 'url' ,
126
- 'http.method' : event . request . method ,
127
- } ,
128
- name : routeName ,
129
- } ,
130
- async ( span ?: Span ) => {
131
- getCurrentScope ( ) . setSDKProcessingMetadata ( {
132
- // We specifically avoid cloning the request here to avoid double read errors.
133
- // We only read request headers so we're not consuming the body anyway.
134
- // Note to future readers: This sounds counter-intuitive but please read
135
- // https://github.com/getsentry/sentry-javascript/issues/14583
136
- normalizedRequest : winterCGRequestToRequestData ( event . request ) ,
137
- } ) ;
138
- const res = await resolve ( event , {
139
- transformPageChunk : addSentryCodeToPage ( { injectFetchProxyScript : options . injectFetchProxyScript ?? true } ) ,
140
- } ) ;
141
- if ( span ) {
142
- setHttpStatus ( span , res . status ) ;
143
- }
144
- return res ;
145
- } ,
146
- ) ;
133
+ const resolveWithSentry : ( span ?: Span ) => Promise < Response > = async ( span ?: Span ) => {
134
+ getCurrentScope ( ) . setSDKProcessingMetadata ( {
135
+ // We specifically avoid cloning the request here to avoid double read errors.
136
+ // We only read request headers so we're not consuming the body anyway.
137
+ // Note to future readers: This sounds counter-intuitive but please read
138
+ // https://github.com/getsentry/sentry-javascript/issues/14583
139
+ normalizedRequest : winterCGRequestToRequestData ( event . request ) ,
140
+ } ) ;
141
+ const res = await resolve ( event , {
142
+ transformPageChunk : addSentryCodeToPage ( {
143
+ injectFetchProxyScript : options . injectFetchProxyScript ?? true ,
144
+ } ) ,
145
+ } ) ;
146
+ if ( span ) {
147
+ setHttpStatus ( span , res . status ) ;
148
+ }
149
+ return res ;
150
+ } ;
151
+
152
+ const resolveResult = shouldStartSpan
153
+ ? await startSpan (
154
+ {
155
+ op : 'http.server' ,
156
+ attributes : {
157
+ [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.http.sveltekit' ,
158
+ [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : routeId ? 'route' : 'url' ,
159
+ 'http.method' : event . request . method ,
160
+ } ,
161
+ name : routeName ,
162
+ } ,
163
+ resolveWithSentry ,
164
+ )
165
+ : await resolveWithSentry ( ) ;
147
166
return resolveResult ;
148
167
} catch ( e : unknown ) {
149
168
sendErrorToSentry ( e , 'handle' ) ;
@@ -153,6 +172,19 @@ async function instrumentHandle(
153
172
}
154
173
}
155
174
175
+ interface BackwardsForwardsCompatibleEvent {
176
+ /**
177
+ * For now taken from: https://github.com/sveltejs/kit/pull/13899
178
+ * Access to spans for tracing. If tracing is not enabled or the function is being run in the browser, these spans will do nothing.
179
+ * @since 2.30.0
180
+ */
181
+ tracing ?: {
182
+ /** Whether tracing is enabled. */
183
+ enabled : boolean ;
184
+ // omitting other properties for now, since we don't use them.
185
+ } ;
186
+ }
187
+
156
188
/**
157
189
* A SvelteKit handle function that wraps the request for Sentry error and
158
190
* performance monitoring.
@@ -176,18 +208,26 @@ export function sentryHandle(handlerOptions?: SentryHandleOptions): Handle {
176
208
} ;
177
209
178
210
const sentryRequestHandler : Handle = input => {
211
+ const backwardsForwardsCompatibleEvent = input . event as typeof input . event & BackwardsForwardsCompatibleEvent ;
212
+
179
213
// Escape hatch to suppress request isolation and trace continuation (see initCloudflareSentryHandle)
180
214
const skipIsolation =
181
- '_sentrySkipRequestIsolation' in input . event . locals && input . event . locals . _sentrySkipRequestIsolation ;
215
+ '_sentrySkipRequestIsolation' in backwardsForwardsCompatibleEvent . locals &&
216
+ backwardsForwardsCompatibleEvent . locals . _sentrySkipRequestIsolation ;
217
+
218
+ const svelteKitTracingEnabled = ! ! backwardsForwardsCompatibleEvent . tracing ?. enabled ;
182
219
183
220
// In case of a same-origin `fetch` call within a server`load` function,
184
221
// SvelteKit will actually just re-enter the `handle` function and set `isSubRequest`
185
222
// to `true` so that no additional network call is made.
186
223
// We want the `http.server` span of that nested call to be a child span of the
187
224
// currently active span instead of a new root span to correctly reflect this
188
225
// behavior.
189
- if ( skipIsolation || input . event . isSubRequest ) {
190
- return instrumentHandle ( input , options ) ;
226
+ if ( skipIsolation || input . event . isSubRequest || svelteKitTracingEnabled ) {
227
+ return instrumentHandle ( input , {
228
+ ...options ,
229
+ svelteKitTracingEnabled,
230
+ } ) ;
191
231
}
192
232
193
233
return withIsolationScope ( isolationScope => {
@@ -200,7 +240,12 @@ export function sentryHandle(handlerOptions?: SentryHandleOptions): Handle {
200
240
// https://github.com/getsentry/sentry-javascript/issues/14583
201
241
normalizedRequest : winterCGRequestToRequestData ( input . event . request ) ,
202
242
} ) ;
203
- return continueTrace ( getTracePropagationData ( input . event ) , ( ) => instrumentHandle ( input , options ) ) ;
243
+ return continueTrace ( getTracePropagationData ( input . event ) , ( ) =>
244
+ instrumentHandle ( input , {
245
+ ...options ,
246
+ svelteKitTracingEnabled,
247
+ } ) ,
248
+ ) ;
204
249
} ) ;
205
250
} ;
206
251
0 commit comments