@@ -5,14 +5,15 @@ import {
55 SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ,
66 addTracingExtensions ,
77} from '@sentry/core' ;
8- import { getClient , getCurrentScope , getIsolationScope , init } from '@sentry/node' ;
8+ import { NodeClient , getCurrentScope , getIsolationScope , setCurrentClient } from '@sentry/node' ;
99import * as SentryNode from '@sentry/node' ;
10- import type { Event } from '@sentry/types' ;
10+ import type { Event , EventEnvelopeHeaders } from '@sentry/types' ;
1111import type { Load , ServerLoad } from '@sveltejs/kit' ;
1212import { error , redirect } from '@sveltejs/kit' ;
1313import { vi } from 'vitest' ;
1414
1515import { wrapLoadWithSentry , wrapServerLoadWithSentry } from '../../src/server/load' ;
16+ import { getDefaultNodeClientOptions } from '../utils' ;
1617
1718const mockCaptureException = vi . spyOn ( SentryNode , 'captureException' ) . mockImplementation ( ( ) => 'xx' ) ;
1819
@@ -192,7 +193,7 @@ describe.each([
192193 } ) ;
193194 } ) ;
194195} ) ;
195- describe ( 'wrapLoadWithSentry calls trace ' , ( ) => {
196+ describe ( 'wrapLoadWithSentry calls `startSpan` ' , ( ) => {
196197 async function load ( { params } ) : Promise < ReturnType < Load > > {
197198 return {
198199 post : params . id ,
@@ -243,7 +244,7 @@ describe('wrapLoadWithSentry calls trace', () => {
243244 } ) ;
244245} ) ;
245246
246- describe ( 'wrapServerLoadWithSentry calls trace ' , ( ) => {
247+ describe ( 'wrapServerLoadWithSentry calls `startSpan` ' , ( ) => {
247248 async function serverLoad ( { params } ) : Promise < ReturnType < ServerLoad > > {
248249 return {
249250 post : params . id ,
@@ -255,46 +256,63 @@ describe('wrapServerLoadWithSentry calls trace', () => {
255256 getIsolationScope ( ) . clear ( ) ;
256257 } ) ;
257258
258- it ( 'attaches trace data if available' , async ( ) => {
259- const transactions : Event [ ] = [ ] ;
259+ let client : NodeClient ;
260260
261- init ( {
262- enableTracing : true ,
263- release : '8.0.0' ,
264- dsn :
'https://[email protected] /1337' , 265- beforeSendTransaction : event => {
266- transactions . push ( event ) ;
267- return null ;
261+ let txnEvents : Event [ ] = [ ] ;
262+
263+ beforeEach ( ( ) => {
264+ txnEvents = [ ] ;
265+
266+ const options = getDefaultNodeClientOptions ( {
267+ tracesSampleRate : 1.0 ,
268+ beforeSendTransaction : evt => {
269+ txnEvents . push ( evt ) ;
270+ return evt ;
268271 } ,
272+ dsn :
'https://[email protected] /1337' , 273+ release : '8.0.0' ,
274+ debug : true ,
275+ } ) ;
276+
277+ client = new NodeClient ( options ) ;
278+ setCurrentClient ( client ) ;
279+ client . init ( ) ;
280+
281+ mockCaptureException . mockClear ( ) ;
282+ } ) ;
283+
284+ it ( 'attaches trace data if available' , async ( ) => {
285+ let envelopeHeaders : EventEnvelopeHeaders | undefined = undefined ;
286+
287+ client . on ( 'beforeEnvelope' , env => {
288+ envelopeHeaders = env [ 0 ] as EventEnvelopeHeaders ;
269289 } ) ;
270- const client = getClient ( ) ! ;
271290
272291 const wrappedLoad = wrapServerLoadWithSentry ( serverLoad ) ;
273292 await wrappedLoad ( getServerOnlyArgs ( ) ) ;
274293
275294 await client . flush ( ) ;
276295
277- expect ( transactions ) . toHaveLength ( 1 ) ;
278- const transaction = transactions [ 0 ] ;
296+ expect ( txnEvents ) . toHaveLength ( 1 ) ;
297+ const transaction = txnEvents [ 0 ] ;
279298
280299 expect ( transaction . contexts ?. trace ) . toEqual ( {
281300 data : {
282301 [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.function.sveltekit' ,
283302 [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : 'route' ,
284303 [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'function.sveltekit.server.load' ,
285304 'http.method' : 'GET' ,
286- 'otel.kind' : 'INTERNAL' ,
287- 'sentry.sample_rate' : 1 ,
288305 } ,
289306 op : 'function.sveltekit.server.load' ,
290307 parent_span_id : '1234567890abcdef' ,
291308 span_id : expect . any ( String ) ,
292309 trace_id : '1234567890abcdef1234567890abcdef' ,
293310 origin : 'auto.function.sveltekit' ,
294- status : 'ok' ,
295311 } ) ;
312+
296313 expect ( transaction . transaction ) . toEqual ( '/users/[id]' ) ;
297- expect ( transaction . sdkProcessingMetadata ?. dynamicSamplingContext ) . toEqual ( {
314+
315+ expect ( envelopeHeaders ! . trace ) . toEqual ( {
298316 environment : 'production' ,
299317 public_key : 'dogsarebadatkeepingsecrets' ,
300318 release : '1.0.0' ,
@@ -305,28 +323,19 @@ describe('wrapServerLoadWithSentry calls trace', () => {
305323 } ) ;
306324
307325 it ( "doesn't attach trace data if it's not available" , async ( ) => {
308- const transactions : Event [ ] = [ ] ;
326+ let envelopeHeaders : EventEnvelopeHeaders | undefined = undefined ;
309327
310- init ( {
311- enableTracing : true ,
312- release : '8.0.0' ,
313- dsn :
'https://[email protected] /1337' , 314- beforeSendTransaction : event => {
315- transactions . push ( event ) ;
316- return null ;
317- } ,
328+ client . on ( 'beforeEnvelope' , env => {
329+ envelopeHeaders = env [ 0 ] as EventEnvelopeHeaders ;
318330 } ) ;
319- const client = getClient ( ) ! ;
320331
321332 const wrappedLoad = wrapServerLoadWithSentry ( serverLoad ) ;
322333 await wrappedLoad ( getServerArgsWithoutTracingHeaders ( ) ) ;
323334
324335 await client . flush ( ) ;
325336
326- expect ( transactions ) . toHaveLength ( 1 ) ;
327- const transaction = transactions [ 0 ] ;
328-
329- console . log ( JSON . stringify ( transaction . contexts ?. trace , null , 2 ) ) ;
337+ expect ( txnEvents ) . toHaveLength ( 1 ) ;
338+ const transaction = txnEvents [ 0 ] ;
330339
331340 expect ( transaction . contexts ?. trace ) . toEqual ( {
332341 data : {
@@ -335,16 +344,14 @@ describe('wrapServerLoadWithSentry calls trace', () => {
335344 [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'function.sveltekit.server.load' ,
336345 [ SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE ] : 1 ,
337346 'http.method' : 'GET' ,
338- 'otel.kind' : 'INTERNAL' ,
339347 } ,
340348 op : 'function.sveltekit.server.load' ,
341349 span_id : expect . any ( String ) ,
342350 trace_id : expect . not . stringContaining ( '1234567890abcdef1234567890abcdef' ) ,
343351 origin : 'auto.function.sveltekit' ,
344- status : 'ok' ,
345352 } ) ;
346353 expect ( transaction . transaction ) . toEqual ( '/users/[id]' ) ;
347- expect ( transaction . sdkProcessingMetadata ?. dynamicSamplingContext ) . toEqual ( {
354+ expect ( envelopeHeaders ! . trace ) . toEqual ( {
348355 environment : 'production' ,
349356 public_key : 'public' ,
350357 sample_rate : '1' ,
@@ -356,59 +363,38 @@ describe('wrapServerLoadWithSentry calls trace', () => {
356363 } ) ;
357364
358365 it ( "doesn't attach the DSC data if the baggage header is not available" , async ( ) => {
359- const transactions : Event [ ] = [ ] ;
366+ let envelopeHeaders : EventEnvelopeHeaders | undefined = undefined ;
360367
361- init ( {
362- enableTracing : true ,
363- dsn :
'https://[email protected] /1337' , 364- beforeSendTransaction : event => {
365- transactions . push ( event ) ;
366- return null ;
367- } ,
368+ client . on ( 'beforeEnvelope' , env => {
369+ envelopeHeaders = env [ 0 ] as EventEnvelopeHeaders ;
368370 } ) ;
369- const client = getClient ( ) ! ;
370371
371372 const wrappedLoad = wrapServerLoadWithSentry ( serverLoad ) ;
372373 await wrappedLoad ( getServerArgsWithoutBaggageHeader ( ) ) ;
373374
374375 await client . flush ( ) ;
375376
376- expect ( transactions ) . toHaveLength ( 1 ) ;
377- const transaction = transactions [ 0 ] ;
377+ expect ( txnEvents ) . toHaveLength ( 1 ) ;
378+ const transaction = txnEvents [ 0 ] ;
378379
379380 expect ( transaction . contexts ?. trace ) . toEqual ( {
380381 data : {
381382 [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.function.sveltekit' ,
382383 [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : 'route' ,
383384 [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'function.sveltekit.server.load' ,
384385 'http.method' : 'GET' ,
385- 'otel.kind' : 'INTERNAL' ,
386- 'sentry.sample_rate' : 1 ,
387386 } ,
388387 op : 'function.sveltekit.server.load' ,
389388 parent_span_id : '1234567890abcdef' ,
390389 span_id : expect . any ( String ) ,
391390 trace_id : '1234567890abcdef1234567890abcdef' ,
392391 origin : 'auto.function.sveltekit' ,
393- status : 'ok' ,
394392 } ) ;
395393 expect ( transaction . transaction ) . toEqual ( '/users/[id]' ) ;
396- expect ( transaction . sdkProcessingMetadata ?. dynamicSamplingContext ) . toEqual ( { } ) ;
394+ expect ( envelopeHeaders ! . trace ) . toEqual ( { } ) ;
397395 } ) ;
398396
399397 it ( 'falls back to the raw url if `event.route.id` is not available' , async ( ) => {
400- const transactions : Event [ ] = [ ] ;
401-
402- init ( {
403- enableTracing : true ,
404- dsn :
'https://[email protected] /1337' , 405- beforeSendTransaction : event => {
406- transactions . push ( event ) ;
407- return null ;
408- } ,
409- } ) ;
410- const client = getClient ( ) ! ;
411-
412398 const event = getServerOnlyArgs ( ) ;
413399 // @ts -expect-error - this is fine (just tests here)
414400 delete event . route ;
@@ -417,24 +403,21 @@ describe('wrapServerLoadWithSentry calls trace', () => {
417403
418404 await client . flush ( ) ;
419405
420- expect ( transactions ) . toHaveLength ( 1 ) ;
421- const transaction = transactions [ 0 ] ;
406+ expect ( txnEvents ) . toHaveLength ( 1 ) ;
407+ const transaction = txnEvents [ 0 ] ;
422408
423409 expect ( transaction . contexts ?. trace ) . toEqual ( {
424410 data : {
425411 [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.function.sveltekit' ,
426412 [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : 'url' ,
427413 [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'function.sveltekit.server.load' ,
428414 'http.method' : 'GET' ,
429- 'otel.kind' : 'INTERNAL' ,
430- 'sentry.sample_rate' : 1 ,
431415 } ,
432416 op : 'function.sveltekit.server.load' ,
433417 parent_span_id : '1234567890abcdef' ,
434418 span_id : expect . any ( String ) ,
435419 trace_id : '1234567890abcdef1234567890abcdef' ,
436420 origin : 'auto.function.sveltekit' ,
437- status : 'ok' ,
438421 } ) ;
439422 expect ( transaction . transaction ) . toEqual ( '/users/123' ) ;
440423 } ) ;
0 commit comments