@@ -61,11 +61,10 @@ test('BullMQ processor breadcrumbs do not leak into subsequent HTTP requests', a
6161 expect ( leakedBreadcrumb ) . toBeUndefined ( ) ;
6262} ) ;
6363
64- // TODO: @OnWorkerEvent handlers run outside the isolation scope created by process().
64+ // TODO: @OnWorkerEvent ('completed') handlers run outside the isolation scope created by process().
6565// They are registered via worker.on() (EventEmitter), so breadcrumbs/tags set there
6666// leak into the default isolation scope and appear on subsequent HTTP requests.
67- // This should be fixed in a follow-up by also wrapping lifecycle event handlers.
68- test ( 'BullMQ @OnWorkerEvent lifecycle breadcrumbs currently leak into subsequent HTTP requests' , async ( {
67+ test ( 'BullMQ @OnWorkerEvent completed lifecycle breadcrumbs currently leak into subsequent HTTP requests' , async ( {
6968 baseURL,
7069} ) => {
7170 const processTransactionPromise = waitForTransaction ( 'nestjs-bullmq' , transactionEvent => {
@@ -91,3 +90,87 @@ test('BullMQ @OnWorkerEvent lifecycle breadcrumbs currently leak into subsequent
9190 // This SHOULD be toBeUndefined() once lifecycle event isolation is implemented.
9291 expect ( leakedBreadcrumb ) . toBeDefined ( ) ;
9392} ) ;
93+
94+ // TODO: @OnWorkerEvent ('active') handlers run outside the isolation scope created by process().
95+ // Breadcrumbs set there leak into the default isolation scope and appear on subsequent HTTP requests.
96+ test ( 'BullMQ @OnWorkerEvent active lifecycle breadcrumbs currently leak into subsequent HTTP requests' , async ( {
97+ baseURL,
98+ } ) => {
99+ const processTransactionPromise = waitForTransaction ( 'nestjs-bullmq' , transactionEvent => {
100+ return transactionEvent . contexts ?. trace ?. op === 'queue.process' ;
101+ } ) ;
102+
103+ await fetch ( `${ baseURL } /enqueue/lifecycle-active-breadcrumb-test` ) ;
104+
105+ await processTransactionPromise ;
106+
107+ const transactionPromise = waitForTransaction ( 'nestjs-bullmq' , transactionEvent => {
108+ return transactionEvent . transaction === 'GET /check-isolation' ;
109+ } ) ;
110+
111+ await fetch ( `${ baseURL } /check-isolation` ) ;
112+
113+ const transaction = await transactionPromise ;
114+
115+ const leakedBreadcrumb = ( transaction . breadcrumbs || [ ] ) . find (
116+ ( b : any ) => b . message === 'leaked-breadcrumb-from-active-event' ,
117+ ) ;
118+ // This SHOULD be toBeUndefined() once lifecycle event isolation is implemented.
119+ expect ( leakedBreadcrumb ) . toBeDefined ( ) ;
120+ } ) ;
121+
122+ // TODO: @OnWorkerEvent ('failed') handlers run outside the isolation scope created by process().
123+ // Breadcrumbs set there leak into the default isolation scope and appear on subsequent HTTP requests.
124+ test ( 'BullMQ @OnWorkerEvent failed lifecycle breadcrumbs currently leak into subsequent HTTP requests' , async ( {
125+ baseURL,
126+ } ) => {
127+ const processTransactionPromise = waitForTransaction ( 'nestjs-bullmq' , transactionEvent => {
128+ return transactionEvent . contexts ?. trace ?. op === 'queue.process' ;
129+ } ) ;
130+
131+ await fetch ( `${ baseURL } /enqueue/lifecycle-failed-breadcrumb-test` ) ;
132+
133+ await processTransactionPromise ;
134+
135+ const transactionPromise = waitForTransaction ( 'nestjs-bullmq' , transactionEvent => {
136+ return transactionEvent . transaction === 'GET /check-isolation' ;
137+ } ) ;
138+
139+ await fetch ( `${ baseURL } /check-isolation` ) ;
140+
141+ const transaction = await transactionPromise ;
142+
143+ const leakedBreadcrumb = ( transaction . breadcrumbs || [ ] ) . find (
144+ ( b : any ) => b . message === 'leaked-breadcrumb-from-failed-event' ,
145+ ) ;
146+ // This SHOULD be toBeUndefined() once lifecycle event isolation is implemented.
147+ expect ( leakedBreadcrumb ) . toBeDefined ( ) ;
148+ } ) ;
149+
150+ // The 'progress' event does NOT leak breadcrumbs — unlike 'active', 'completed', and 'failed',
151+ // BullMQ emits it inside the process() call (via job.updateProgress()), so it runs within
152+ // the isolation scope already established by the instrumentation.
153+ test ( 'BullMQ @OnWorkerEvent progress lifecycle breadcrumbs do not leak into subsequent HTTP requests' , async ( {
154+ baseURL,
155+ } ) => {
156+ const processTransactionPromise = waitForTransaction ( 'nestjs-bullmq' , transactionEvent => {
157+ return transactionEvent . contexts ?. trace ?. op === 'queue.process' ;
158+ } ) ;
159+
160+ await fetch ( `${ baseURL } /enqueue/lifecycle-progress-breadcrumb-test` ) ;
161+
162+ await processTransactionPromise ;
163+
164+ const transactionPromise = waitForTransaction ( 'nestjs-bullmq' , transactionEvent => {
165+ return transactionEvent . transaction === 'GET /check-isolation' ;
166+ } ) ;
167+
168+ await fetch ( `${ baseURL } /check-isolation` ) ;
169+
170+ const transaction = await transactionPromise ;
171+
172+ const leakedBreadcrumb = ( transaction . breadcrumbs || [ ] ) . find (
173+ ( b : any ) => b . message === 'leaked-breadcrumb-from-progress-event' ,
174+ ) ;
175+ expect ( leakedBreadcrumb ) . toBeUndefined ( ) ;
176+ } ) ;
0 commit comments