@@ -90,6 +90,14 @@ interface MongoOptions {
9090 useMongoose ?: boolean ;
9191}
9292
93+ interface MongoCursor {
94+ once ( event : 'close' , listener : ( ) => void ) : void ;
95+ }
96+
97+ function isCursor ( maybeCursor : MongoCursor ) : maybeCursor is MongoCursor {
98+ return maybeCursor && typeof maybeCursor === 'object' && maybeCursor . once && typeof maybeCursor . once === 'function' ;
99+ }
100+
93101/** Tracing integration for mongo package */
94102export class Mongo implements Integration {
95103 /**
@@ -160,20 +168,38 @@ export class Mongo implements Integration {
160168 // its (non-callback) arguments can also be functions.)
161169 if ( typeof lastArg !== 'function' || ( operation === 'mapReduce' && args . length === 2 ) ) {
162170 const span = parentSpan ?. startChild ( getSpanContext ( this , operation , args ) ) ;
163- const maybePromise = orig . call ( this , ...args ) as Promise < unknown > ;
171+ const maybePromiseOrCursor = orig . call ( this , ...args ) ;
164172
165- if ( isThenable ( maybePromise ) ) {
166- return maybePromise . then ( ( res : unknown ) => {
173+ if ( isThenable ( maybePromiseOrCursor ) ) {
174+ return maybePromiseOrCursor . then ( ( res : unknown ) => {
167175 span ?. finish ( ) ;
168176 return res ;
169177 } ) ;
178+ }
179+ // If the operation returns a Cursor
180+ // we need to attach a listener to it to finish the span when the cursor is closed.
181+ else if ( isCursor ( maybePromiseOrCursor ) ) {
182+ const cursor = maybePromiseOrCursor as MongoCursor ;
183+
184+ try {
185+ cursor . once ( 'close' , ( ) => {
186+ span ?. finish ( ) ;
187+ } ) ;
188+ } catch ( e ) {
189+ // If the cursor is already closed, `once` will throw an error. In that case, we can
190+ // finish the span immediately.
191+ span ?. finish ( ) ;
192+ }
193+
194+ return cursor ;
170195 } else {
171196 span ?. finish ( ) ;
172- return maybePromise ;
197+ return maybePromiseOrCursor ;
173198 }
174199 }
175200
176201 const span = parentSpan ?. startChild ( getSpanContext ( this , operation , args . slice ( 0 , - 1 ) ) ) ;
202+
177203 return orig . call ( this , ...args . slice ( 0 , - 1 ) , function ( err : Error , result : unknown ) {
178204 span ?. finish ( ) ;
179205 lastArg ( err , result ) ;
0 commit comments