node icon indicating copy to clipboard operation
node copied to clipboard

stream.pipeline doesn't wait for 'close' on error

Open wh0 opened this issue 1 year ago • 0 comments

Version

v20.11.0

Platform

Linux cs-63018580108-ephemeral-4kum 6.1.58+ #1 SMP PREEMPT_DYNAMIC Sat Dec 30 15:31:26 UTC 2023 x86_64 GNU/Linux

Subsystem

internal/streams/pipeline

What steps will reproduce the bug?

const stream = require('stream');

const src = new stream.Readable();
const dst = new stream.Writable({
  write(chunk, encoding, callback) {
    callback();
  },
  destroy(error, callback) {
    // takes a while to destroy
    setImmediate(() => {
      callback(error);
    });
  },
});

stream.pipeline(src, dst, (err) => {
  console.log(`pipeline done, err=${err.message}, dst.closed=${dst.closed}`);
});
src.destroy(new Error('problem'));

How often does it reproduce? Is there a required condition?

always

What is the expected behavior? Why is that the expected behavior?

dst.closed=true

maybe? #32158 sounds like it should

What do you see instead?

pipeline done, err=problem, dst.closed=false

Additional information

I notice that this finishCount countdown goes from 2 down to -3.

  1. (2 -> 1) src error event ("Catch stream errors that occur after pipe/pump has completed.")
  2. (1 -> 0, final) src err event (same one) (pipe src eos onerror)
  3. (0 -> -1) dst error event ("Catch stream errors that occur after pipe/pump has completed.")
  4. (-1 -> -2) dst error event (same one) (pipe dst eos onerror)
  5. (-2 -> -3) dst close event ("Finish if the destination closes before the source has completed.")

wh0 avatar Jan 22 '24 05:01 wh0