From d1e81b0f17a3b49167f16318147afe8d644db46c Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 26 Apr 2018 13:49:12 -0700 Subject: [PATCH] stream: ensure Stream.pipeline re-throws errors without callback Fixes an issue where Stream.pipeline wouldn't re-throw errors on a stream if no callback was specified, thus swallowing said errors. Fixes: https://github.com/nodejs/node/issues/20303 PR-URL: https://github.com/nodejs/node/pull/20437 Reviewed-By: Anna Henningsen Reviewed-By: Matteo Collina --- lib/internal/streams/pipeline.js | 5 +++- test/parallel/test-stream-pipeline.js | 38 ++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/lib/internal/streams/pipeline.js b/lib/internal/streams/pipeline.js index 1178108842be61..849b3d39dbe25b 100644 --- a/lib/internal/streams/pipeline.js +++ b/lib/internal/streams/pipeline.js @@ -19,7 +19,10 @@ function once(callback) { }; } -function noop() {} +function noop(err) { + // Rethrow the error if it exists to avoid swallowing it + if (err) throw err; +} function isRequest(stream) { return stream.setHeader && typeof stream.abort === 'function'; diff --git a/test/parallel/test-stream-pipeline.js b/test/parallel/test-stream-pipeline.js index e63ee2ed117679..b52d60529b0332 100644 --- a/test/parallel/test-stream-pipeline.js +++ b/test/parallel/test-stream-pipeline.js @@ -142,7 +142,7 @@ common.crashOnUnhandledRejection(); } }); - pipeline(rs, res); + pipeline(rs, res, () => {}); }); server.listen(0, () => { @@ -177,7 +177,7 @@ common.crashOnUnhandledRejection(); }) }); - pipeline(rs, res); + pipeline(rs, res, () => {}); }); server.listen(0, () => { @@ -206,7 +206,7 @@ common.crashOnUnhandledRejection(); }) }); - pipeline(rs, res); + pipeline(rs, res, () => {}); }); let cnt = 10; @@ -481,3 +481,35 @@ common.crashOnUnhandledRejection(); run(); } + +{ + const read = new Readable({ + read() {} + }); + + const transform = new Transform({ + transform(data, enc, cb) { + cb(new Error('kaboom')); + } + }); + + const write = new Writable({ + write(data, enc, cb) { + cb(); + } + }); + + read.on('close', common.mustCall()); + transform.on('close', common.mustCall()); + write.on('close', common.mustCall()); + + process.on('uncaughtException', common.mustCall((err) => { + assert.deepStrictEqual(err, new Error('kaboom')); + })); + + const dst = pipeline(read, transform, write); + + assert.strictEqual(dst, write); + + read.push('hello'); +}