@@ -46,6 +46,7 @@ const CHANGE_DOMAIN_TYPES = {
46
46
const NO_RESUME_TOKEN_ERROR = new MongoError (
47
47
'A change stream document has been received that lacks a resume token (_id).'
48
48
) ;
49
+ const NO_CURSOR_ERROR = new MongoError ( 'ChangeStream has no cursor' ) ;
49
50
const CHANGESTREAM_CLOSED_ERROR = new MongoError ( 'ChangeStream is closed' ) ;
50
51
51
52
/** @public */
@@ -287,8 +288,7 @@ export class ChangeStream extends EventEmitter {
287
288
next ( callback ?: Callback ) : Promise < void > | void {
288
289
return maybePromise ( callback , cb => {
289
290
getCursor ( this , ( err , cursor ) => {
290
- if ( err ) return cb ( err ) ; // failed to resume, raise an error
291
- if ( ! cursor ) return cb ( new MongoError ( 'Cursor is undefined' ) ) ;
291
+ if ( err || ! cursor ) return cb ( err ) ; // failed to resume, raise an error
292
292
cursor . next ( ( error , change ) => {
293
293
if ( error ) {
294
294
this [ kResumeQueue ] . push ( ( ) => this . next ( cb ) ) ;
@@ -330,11 +330,23 @@ export class ChangeStream extends EventEmitter {
330
330
*/
331
331
stream ( options ?: CursorStreamOptions ) : Readable {
332
332
this . streamOptions = options ;
333
- if ( ! this . cursor ) {
334
- throw new MongoError ( 'ChangeStream has no cursor, unable to stream' ) ;
335
- }
333
+ if ( ! this . cursor ) throw NO_CURSOR_ERROR ;
336
334
return this . cursor . stream ( options ) ;
337
335
}
336
+
337
+ /**
338
+ * Try to get the next available document from the Change Stream's cursor or `null` if an empty batch is returned
339
+ */
340
+ tryNext ( ) : Promise < Document | null > ;
341
+ tryNext ( callback : Callback < Document | null > ) : void ;
342
+ tryNext ( callback ?: Callback < Document | null > ) : Promise < Document | null > | void {
343
+ return maybePromise ( callback , cb => {
344
+ getCursor ( this , ( err , cursor ) => {
345
+ if ( err || ! cursor ) return cb ( err ) ; // failed to resume, raise an error
346
+ return cursor . tryNext ( cb ) ;
347
+ } ) ;
348
+ } ) ;
349
+ }
338
350
}
339
351
340
352
/** @internal */
@@ -707,11 +719,16 @@ function getCursor(changeStream: ChangeStream, callback: Callback<ChangeStreamCu
707
719
function processResumeQueue ( changeStream : ChangeStream , err ?: Error ) {
708
720
while ( changeStream [ kResumeQueue ] . length ) {
709
721
const request = changeStream [ kResumeQueue ] . pop ( ) ;
710
- if ( changeStream [ kClosed ] && ! err ) {
711
- request ( CHANGESTREAM_CLOSED_ERROR ) ;
712
- return ;
722
+ if ( ! err ) {
723
+ if ( changeStream [ kClosed ] ) {
724
+ request ( CHANGESTREAM_CLOSED_ERROR ) ;
725
+ return ;
726
+ }
727
+ if ( ! changeStream . cursor ) {
728
+ request ( NO_CURSOR_ERROR ) ;
729
+ return ;
730
+ }
713
731
}
714
-
715
732
request ( err , changeStream . cursor ) ;
716
733
}
717
734
}
0 commit comments