Skip to content

Commit ecfc615

Browse files
vkarpov15durran
andauthored
fix(NODE-5901): propagate errors to transformed stream in cursor (#3985)
Co-authored-by: Durran Jordan <[email protected]>
1 parent a63fbc2 commit ecfc615

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

src/cursor/abstract_cursor.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ export abstract class AbstractCursor<
337337
const transform = options.transform;
338338
const readable = new ReadableCursorStream(this);
339339

340-
return readable.pipe(
340+
const transformedStream = readable.pipe(
341341
new Transform({
342342
objectMode: true,
343343
highWaterMark: 1,
@@ -351,6 +351,12 @@ export abstract class AbstractCursor<
351351
}
352352
})
353353
);
354+
355+
// Bubble errors to transformed stream, because otherwise no way
356+
// to handle this error.
357+
readable.on('error', err => transformedStream.emit('error', err));
358+
359+
return transformedStream;
354360
}
355361

356362
return new ReadableCursorStream(this);

test/integration/node-specific/abstract_cursor.test.ts

+43-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
import { expect } from 'chai';
22
import { once } from 'events';
33
import * as sinon from 'sinon';
4+
import { Transform } from 'stream';
45
import { inspect } from 'util';
56

6-
import { type Collection, type FindCursor, MongoAPIError, type MongoClient } from '../../mongodb';
7+
import {
8+
type Collection,
9+
type FindCursor,
10+
MongoAPIError,
11+
type MongoClient,
12+
MongoServerError
13+
} from '../../mongodb';
714

815
describe('class AbstractCursor', function () {
916
describe('regression tests NODE-5372', function () {
@@ -233,4 +240,39 @@ describe('class AbstractCursor', function () {
233240
});
234241
});
235242
});
243+
244+
describe('transform stream error handling', function () {
245+
let client: MongoClient;
246+
let collection: Collection;
247+
const docs = [{ count: 0 }];
248+
beforeEach(async function () {
249+
client = this.configuration.newClient();
250+
251+
collection = client.db('abstract_cursor_integration').collection('test');
252+
253+
await collection.insertMany(docs);
254+
});
255+
256+
afterEach(async function () {
257+
await collection.deleteMany({});
258+
await client.close();
259+
});
260+
261+
it('propagates errors to transform stream', async function () {
262+
const transform = new Transform({
263+
transform(data, encoding, callback) {
264+
callback(null, data);
265+
}
266+
});
267+
268+
// MongoServerError: unknown operator: $bar
269+
const stream = collection.find({ foo: { $bar: 25 } }).stream({ transform });
270+
271+
const error: Error | null = await new Promise(resolve => {
272+
stream.on('error', error => resolve(error));
273+
stream.on('end', () => resolve(null));
274+
});
275+
expect(error).to.be.instanceof(MongoServerError);
276+
});
277+
});
236278
});

0 commit comments

Comments
 (0)