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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions