@@ -5,14 +5,15 @@ import {
5
5
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ,
6
6
addTracingExtensions ,
7
7
} from '@sentry/core' ;
8
- import { getClient , getCurrentScope , getIsolationScope , init } from '@sentry/node' ;
8
+ import { NodeClient , getCurrentScope , getIsolationScope , setCurrentClient } from '@sentry/node' ;
9
9
import * as SentryNode from '@sentry/node' ;
10
- import type { Event } from '@sentry/types' ;
10
+ import type { Event , EventEnvelopeHeaders } from '@sentry/types' ;
11
11
import type { Load , ServerLoad } from '@sveltejs/kit' ;
12
12
import { error , redirect } from '@sveltejs/kit' ;
13
13
import { vi } from 'vitest' ;
14
14
15
15
import { wrapLoadWithSentry , wrapServerLoadWithSentry } from '../../src/server/load' ;
16
+ import { getDefaultNodeClientOptions } from '../utils' ;
16
17
17
18
const mockCaptureException = vi . spyOn ( SentryNode , 'captureException' ) . mockImplementation ( ( ) => 'xx' ) ;
18
19
@@ -192,7 +193,7 @@ describe.each([
192
193
} ) ;
193
194
} ) ;
194
195
} ) ;
195
- describe ( 'wrapLoadWithSentry calls trace ' , ( ) => {
196
+ describe ( 'wrapLoadWithSentry calls `startSpan` ' , ( ) => {
196
197
async function load ( { params } ) : Promise < ReturnType < Load > > {
197
198
return {
198
199
post : params . id ,
@@ -243,7 +244,7 @@ describe('wrapLoadWithSentry calls trace', () => {
243
244
} ) ;
244
245
} ) ;
245
246
246
- describe ( 'wrapServerLoadWithSentry calls trace ' , ( ) => {
247
+ describe ( 'wrapServerLoadWithSentry calls `startSpan` ' , ( ) => {
247
248
async function serverLoad ( { params } ) : Promise < ReturnType < ServerLoad > > {
248
249
return {
249
250
post : params . id ,
@@ -255,46 +256,63 @@ describe('wrapServerLoadWithSentry calls trace', () => {
255
256
getIsolationScope ( ) . clear ( ) ;
256
257
} ) ;
257
258
258
- it ( 'attaches trace data if available' , async ( ) => {
259
- const transactions : Event [ ] = [ ] ;
259
+ let client : NodeClient ;
260
260
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 ;
268
271
} ,
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 ;
269
289
} ) ;
270
- const client = getClient ( ) ! ;
271
290
272
291
const wrappedLoad = wrapServerLoadWithSentry ( serverLoad ) ;
273
292
await wrappedLoad ( getServerOnlyArgs ( ) ) ;
274
293
275
294
await client . flush ( ) ;
276
295
277
- expect ( transactions ) . toHaveLength ( 1 ) ;
278
- const transaction = transactions [ 0 ] ;
296
+ expect ( txnEvents ) . toHaveLength ( 1 ) ;
297
+ const transaction = txnEvents [ 0 ] ;
279
298
280
299
expect ( transaction . contexts ?. trace ) . toEqual ( {
281
300
data : {
282
301
[ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.function.sveltekit' ,
283
302
[ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : 'route' ,
284
303
[ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'function.sveltekit.server.load' ,
285
304
'http.method' : 'GET' ,
286
- 'otel.kind' : 'INTERNAL' ,
287
- 'sentry.sample_rate' : 1 ,
288
305
} ,
289
306
op : 'function.sveltekit.server.load' ,
290
307
parent_span_id : '1234567890abcdef' ,
291
308
span_id : expect . any ( String ) ,
292
309
trace_id : '1234567890abcdef1234567890abcdef' ,
293
310
origin : 'auto.function.sveltekit' ,
294
- status : 'ok' ,
295
311
} ) ;
312
+
296
313
expect ( transaction . transaction ) . toEqual ( '/users/[id]' ) ;
297
- expect ( transaction . sdkProcessingMetadata ?. dynamicSamplingContext ) . toEqual ( {
314
+
315
+ expect ( envelopeHeaders ! . trace ) . toEqual ( {
298
316
environment : 'production' ,
299
317
public_key : 'dogsarebadatkeepingsecrets' ,
300
318
release : '1.0.0' ,
@@ -305,28 +323,19 @@ describe('wrapServerLoadWithSentry calls trace', () => {
305
323
} ) ;
306
324
307
325
it ( "doesn't attach trace data if it's not available" , async ( ) => {
308
- const transactions : Event [ ] = [ ] ;
326
+ let envelopeHeaders : EventEnvelopeHeaders | undefined = undefined ;
309
327
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 ;
318
330
} ) ;
319
- const client = getClient ( ) ! ;
320
331
321
332
const wrappedLoad = wrapServerLoadWithSentry ( serverLoad ) ;
322
333
await wrappedLoad ( getServerArgsWithoutTracingHeaders ( ) ) ;
323
334
324
335
await client . flush ( ) ;
325
336
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 ] ;
330
339
331
340
expect ( transaction . contexts ?. trace ) . toEqual ( {
332
341
data : {
@@ -335,16 +344,14 @@ describe('wrapServerLoadWithSentry calls trace', () => {
335
344
[ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'function.sveltekit.server.load' ,
336
345
[ SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE ] : 1 ,
337
346
'http.method' : 'GET' ,
338
- 'otel.kind' : 'INTERNAL' ,
339
347
} ,
340
348
op : 'function.sveltekit.server.load' ,
341
349
span_id : expect . any ( String ) ,
342
350
trace_id : expect . not . stringContaining ( '1234567890abcdef1234567890abcdef' ) ,
343
351
origin : 'auto.function.sveltekit' ,
344
- status : 'ok' ,
345
352
} ) ;
346
353
expect ( transaction . transaction ) . toEqual ( '/users/[id]' ) ;
347
- expect ( transaction . sdkProcessingMetadata ?. dynamicSamplingContext ) . toEqual ( {
354
+ expect ( envelopeHeaders ! . trace ) . toEqual ( {
348
355
environment : 'production' ,
349
356
public_key : 'public' ,
350
357
sample_rate : '1' ,
@@ -356,59 +363,38 @@ describe('wrapServerLoadWithSentry calls trace', () => {
356
363
} ) ;
357
364
358
365
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 ;
360
367
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 ;
368
370
} ) ;
369
- const client = getClient ( ) ! ;
370
371
371
372
const wrappedLoad = wrapServerLoadWithSentry ( serverLoad ) ;
372
373
await wrappedLoad ( getServerArgsWithoutBaggageHeader ( ) ) ;
373
374
374
375
await client . flush ( ) ;
375
376
376
- expect ( transactions ) . toHaveLength ( 1 ) ;
377
- const transaction = transactions [ 0 ] ;
377
+ expect ( txnEvents ) . toHaveLength ( 1 ) ;
378
+ const transaction = txnEvents [ 0 ] ;
378
379
379
380
expect ( transaction . contexts ?. trace ) . toEqual ( {
380
381
data : {
381
382
[ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.function.sveltekit' ,
382
383
[ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : 'route' ,
383
384
[ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'function.sveltekit.server.load' ,
384
385
'http.method' : 'GET' ,
385
- 'otel.kind' : 'INTERNAL' ,
386
- 'sentry.sample_rate' : 1 ,
387
386
} ,
388
387
op : 'function.sveltekit.server.load' ,
389
388
parent_span_id : '1234567890abcdef' ,
390
389
span_id : expect . any ( String ) ,
391
390
trace_id : '1234567890abcdef1234567890abcdef' ,
392
391
origin : 'auto.function.sveltekit' ,
393
- status : 'ok' ,
394
392
} ) ;
395
393
expect ( transaction . transaction ) . toEqual ( '/users/[id]' ) ;
396
- expect ( transaction . sdkProcessingMetadata ?. dynamicSamplingContext ) . toEqual ( { } ) ;
394
+ expect ( envelopeHeaders ! . trace ) . toEqual ( { } ) ;
397
395
} ) ;
398
396
399
397
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
-
412
398
const event = getServerOnlyArgs ( ) ;
413
399
// @ts -expect-error - this is fine (just tests here)
414
400
delete event . route ;
@@ -417,24 +403,21 @@ describe('wrapServerLoadWithSentry calls trace', () => {
417
403
418
404
await client . flush ( ) ;
419
405
420
- expect ( transactions ) . toHaveLength ( 1 ) ;
421
- const transaction = transactions [ 0 ] ;
406
+ expect ( txnEvents ) . toHaveLength ( 1 ) ;
407
+ const transaction = txnEvents [ 0 ] ;
422
408
423
409
expect ( transaction . contexts ?. trace ) . toEqual ( {
424
410
data : {
425
411
[ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.function.sveltekit' ,
426
412
[ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : 'url' ,
427
413
[ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'function.sveltekit.server.load' ,
428
414
'http.method' : 'GET' ,
429
- 'otel.kind' : 'INTERNAL' ,
430
- 'sentry.sample_rate' : 1 ,
431
415
} ,
432
416
op : 'function.sveltekit.server.load' ,
433
417
parent_span_id : '1234567890abcdef' ,
434
418
span_id : expect . any ( String ) ,
435
419
trace_id : '1234567890abcdef1234567890abcdef' ,
436
420
origin : 'auto.function.sveltekit' ,
437
- status : 'ok' ,
438
421
} ) ;
439
422
expect ( transaction . transaction ) . toEqual ( '/users/123' ) ;
440
423
} ) ;
0 commit comments