11import { context , trace , TraceFlags } from '@opentelemetry/api' ;
2- import type { TransactionEvent } from '@sentry/core' ;
2+ import type { ErrorEvent , TransactionEvent } from '@sentry/core' ;
33import { debug , SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN , SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core' ;
44import { afterEach , describe , expect , it , vi } from 'vitest' ;
55import * as Sentry from '../../src' ;
@@ -9,6 +9,7 @@ describe('Integration | Transactions', () => {
99 afterEach ( ( ) => {
1010 vi . restoreAllMocks ( ) ;
1111 cleanupOtel ( ) ;
12+ vi . useRealTimers ( ) ;
1213 } ) ;
1314
1415 it ( 'correctly creates transaction & spans' , async ( ) => {
@@ -674,4 +675,65 @@ describe('Integration | Transactions', () => {
674675 expect ( spans ) . toContainEqual ( expect . objectContaining ( { description : 'inner span 1' } ) ) ;
675676 expect ( spans ) . toContainEqual ( expect . objectContaining ( { description : 'inner span 2' } ) ) ;
676677 } ) ;
678+
679+ it ( 'withMonitor should use the same traces for each monitor' , async ( ) => {
680+ const sendEvents : ErrorEvent [ ] = [ ] ;
681+ const transactionEvents : TransactionEvent [ ] = [ ] ;
682+ const beforeSendTransaction = vi . fn ( ( event : TransactionEvent ) => {
683+ transactionEvents . push ( event ) ;
684+ return null ;
685+ } ) ;
686+ const beforeSend = vi . fn ( ( event : ErrorEvent ) => {
687+ sendEvents . push ( event ) ;
688+ return null ;
689+ } ) ;
690+
691+ mockSdkInit ( {
692+ tracesSampleRate : 1 ,
693+ beforeSendTransaction,
694+ beforeSend,
695+ debug : true ,
696+ } ) ;
697+
698+ const client = Sentry . getClient ( ) ;
699+ const errorMessage = 'Error outside withMonitor' ;
700+
701+ Sentry . startSpan ( { name : 'span outside error' } , ( ) => {
702+ Sentry . withMonitor ( 'cron-job-1' , ( ) => Sentry . startSpan ( { name : 'inner span 1' } , ( ) => undefined ) ) ;
703+
704+ try {
705+ throw new Error ( errorMessage ) ;
706+ } catch ( e ) {
707+ Sentry . startSpan ( { name : 'span inside error' } , ( ) => undefined ) ;
708+ Sentry . captureException ( e ) ;
709+ }
710+
711+ Sentry . withMonitor ( 'cron-job-2' , ( ) => {
712+ Sentry . startSpan ( { name : 'inner span 2' } , ( ) => undefined ) ;
713+ } ) ;
714+ } ) ;
715+
716+ await client ?. flush ( ) ;
717+
718+ const transactionTraceId = transactionEvents [ 0 ] ?. contexts ?. trace ?. trace_id ;
719+ const errorTraceId = sendEvents [ 0 ] ?. contexts ?. trace ?. trace_id ;
720+
721+ expect ( beforeSendTransaction ) . toHaveBeenCalledTimes ( 1 ) ;
722+ expect ( beforeSend ) . toHaveBeenCalledTimes ( 1 ) ;
723+ expect ( transactionEvents ) . toHaveLength ( 1 ) ;
724+ expect ( transactionTraceId ) . toBe ( errorTraceId ) ;
725+ expect ( transactionEvents [ 0 ] ?. spans ) . toHaveLength ( 3 ) ;
726+ expect ( transactionEvents ) . toMatchObject ( [
727+ {
728+ spans : [ { description : 'inner span 1' } , { description : 'span inside error' } , { description : 'inner span 2' } ] ,
729+ } ,
730+ ] ) ;
731+ expect ( sendEvents ) . toMatchObject ( [
732+ {
733+ exception : {
734+ values : [ { value : errorMessage } ] ,
735+ } ,
736+ } ,
737+ ] ) ;
738+ } ) ;
677739} ) ;
0 commit comments