File tree Expand file tree Collapse file tree 2 files changed +56
-6
lines changed Expand file tree Collapse file tree 2 files changed +56
-6
lines changed Original file line number Diff line number Diff line change @@ -326,21 +326,27 @@ export abstract class AbstractCursor<
326326 const fetchDocs = ( ) => {
327327 next < T > ( this , true , ( err , doc ) => {
328328 if ( err || doc == null ) return done ( err ) ;
329- if ( doc == null ) return done ( ) ;
330-
329+ let result ;
331330 // NOTE: no need to transform because `next` will do this automatically
332- let result = iterator ( doc ) ; // TODO(NODE-3283): Improve transform typing
331+ try {
332+ result = iterator ( doc ) ; // TODO(NODE-3283): Improve transform typing
333+ } catch ( error ) {
334+ return done ( error ) ;
335+ }
336+
333337 if ( result === false ) return done ( ) ;
334338
335339 // these do need to be transformed since they are copying the rest of the batch
336340 const internalDocs = this [ kDocuments ] . splice ( 0 , this [ kDocuments ] . length ) ;
337- if ( internalDocs ) {
338- for ( let i = 0 ; i < internalDocs . length ; ++ i ) {
341+ for ( let i = 0 ; i < internalDocs . length ; ++ i ) {
342+ try {
339343 result = iterator (
340344 ( transform ? transform ( internalDocs [ i ] ) : internalDocs [ i ] ) as T // TODO(NODE-3283): Improve transform typing
341345 ) ;
342- if ( result === false ) return done ( ) ;
346+ } catch ( error ) {
347+ return done ( error ) ;
343348 }
349+ if ( result === false ) return done ( ) ;
344350 }
345351
346352 fetchDocs ( ) ;
Original file line number Diff line number Diff line change @@ -3901,6 +3901,50 @@ describe('Cursor', function () {
39013901 } ) ;
39023902 } ) ;
39033903
3904+ describe ( 'Cursor forEach Error propagation' , function ( ) {
3905+ let configuration ;
3906+ let client ;
3907+ let cursor ;
3908+ let collection ;
3909+
3910+ beforeEach ( async function ( ) {
3911+ configuration = this . configuration ;
3912+ client = configuration . newClient ( { w : 1 } , { maxPoolSize : 1 } ) ;
3913+ await client . connect ( ) . catch ( ( ) => {
3914+ expect . fail ( 'Failed to connect to client' ) ;
3915+ } ) ;
3916+ collection = client . db ( configuration . db ) . collection ( 'cursor_session_tests2' ) ;
3917+ } ) ;
3918+
3919+ afterEach ( async function ( ) {
3920+ await cursor . close ( ) ;
3921+ await client . close ( ) ;
3922+ } ) ;
3923+
3924+ // NODE-2035
3925+ it ( 'should propagate error when exceptions are thrown from an awaited forEach call' , async function ( ) {
3926+ const docs = [ { unique_key_2035 : 1 } , { unique_key_2035 : 2 } , { unique_key_2035 : 3 } ] ;
3927+ await collection . insertMany ( docs ) . catch ( ( ) => {
3928+ expect . fail ( 'Failed to insert documents' ) ;
3929+ } ) ;
3930+ cursor = collection . find ( {
3931+ unique_key_2035 : {
3932+ $exists : true
3933+ }
3934+ } ) ;
3935+ await cursor
3936+ . forEach ( ( ) => {
3937+ throw new Error ( 'FAILURE IN FOREACH CALL' ) ;
3938+ } )
3939+ . then ( ( ) => {
3940+ expect . fail ( 'Error in forEach call not caught' ) ;
3941+ } )
3942+ . catch ( err => {
3943+ expect ( err . message ) . to . deep . equal ( 'FAILURE IN FOREACH CALL' ) ;
3944+ } ) ;
3945+ } ) ;
3946+ } ) ;
3947+
39043948 it ( 'should return a promise when no callback supplied to forEach method' , function ( ) {
39053949 const configuration = this . configuration ;
39063950 const client = configuration . newClient ( { w : 1 } , { maxPoolSize : 1 } ) ;
You can’t perform that action at this time.
0 commit comments