Skip to content

finish event of stream.Writable is not expectedly emitted #11121

@cynron

Description

@cynron
  • Version: v8.0.0-pre/master branch, v6.9.5
  • Subsystem: stream.Writable

Hi,

If _writableState.corked > 0 and _writev callback with an error, after calling writable.end(), finish event is not emitted.

Test Case:

const stream = require('stream');

const writable = new stream.Writable();

writable._write = (chunks, encoding, cb) => {
  cb(new Error('write test error'));
};

writable._writev = (chunks, cb) => {
  cb(new Error('writev test error'));
};

writable.on('finish', () => {
  console.error('finish'); /* it should print "finish", but not */
});

writable.on('prefinish', () => {
  console.error('prefinish');
});

writable.on('error', (er) => {
  console.error('error');
});

writable.cork();
writable.write('test');

setTimeout(function() {
    writable.end('test');
}, 10);

In onwriteError, finishMaybe should also be checked. a test patch for master works:

diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js
index eedeb56..ccda379 100644
--- a/lib/_stream_writable.js
+++ b/lib/_stream_writable.js
@@ -330,9 +330,14 @@ function doWrite(stream, state, writev, len, chunk, encoding, cb) {
 function onwriteError(stream, state, sync, er, cb) {
   --state.pendingcb;
   if (sync)
-    process.nextTick(cb, er);
+    process.nextTick(after, er);
   else
+    after(er);
+
+  function after(er) {
     cb(er);
+    finishMaybe(stream, state);
+  }

   stream._writableState.errorEmitted = true;
   stream.emit('error', er);

Please confirm whether it is a bug? make a PR for this?

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    streamIssues and PRs related to the stream subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions