From de856a4afb8db94f28b9d4db191ac39035b85513 Mon Sep 17 00:00:00 2001 From: jakecastelli <959672929@qq.com> Date: Sun, 16 Jun 2024 00:45:22 +0930 Subject: [PATCH] stream: wait for close before calling the callback The pipeline should wait for close event to finish before calling the callback. The `finishCount` should not below 0 when calling finish function. Fixes: https://github.com/nodejs/node/issues/51540 --- lib/internal/streams/pipeline.js | 4 +++- test/parallel/test-stream-pipeline.js | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/internal/streams/pipeline.js b/lib/internal/streams/pipeline.js index bb34759b1fea12..85a03614ab97af 100644 --- a/lib/internal/streams/pipeline.js +++ b/lib/internal/streams/pipeline.js @@ -277,7 +277,9 @@ function pipelineImpl(streams, callback, opts) { if ( err && err.name !== 'AbortError' && - err.code !== 'ERR_STREAM_PREMATURE_CLOSE' + err.code !== 'ERR_STREAM_PREMATURE_CLOSE' && + // It is 1 not 0 as finishCount will be decremented in finish + finishCount === 1 ) { finish(err); } diff --git a/test/parallel/test-stream-pipeline.js b/test/parallel/test-stream-pipeline.js index 7e69754b36d771..63856d12865c35 100644 --- a/test/parallel/test-stream-pipeline.js +++ b/test/parallel/test-stream-pipeline.js @@ -1678,4 +1678,21 @@ tmpdir.refresh(); assert.strictEqual(err, undefined); })); + { + // See https://github.com/nodejs/node/issues/51540 + const src = new Readable(); + const dst = new Writable({ + destroy(error, cb) { + // Takes a while to destroy + setImmediate(cb); + }, + }); + + pipeline(src, dst, (err) => { + assert.strictEqual(dst.closed, true); + assert.strictEqual(err.message, 'problem'); + }); + src.destroy(new Error('problem')); + } + }