diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index 4e2a19f12c822f..0c7f020bb23c27 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -358,14 +358,19 @@ 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(afterError, stream, state, cb, er); else - cb(er); + afterError(stream, state, cb, er); stream._writableState.errorEmitted = true; stream.emit('error', er); } +function afterError(stream, state, cb, err) { + cb(err); + finishMaybe(stream, state); +} + function onwriteStateUpdate(state) { state.writing = false; state.writecb = null; diff --git a/test/parallel/test-stream-writable-writev-finish.js b/test/parallel/test-stream-writable-writev-finish.js new file mode 100644 index 00000000000000..6f74ca08d2366d --- /dev/null +++ b/test/parallel/test-stream-writable-writev-finish.js @@ -0,0 +1,53 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const stream = require('stream'); + +// ensure consistency between the finish event when using cork() +// and writev and when not using them + +{ + const writable = new stream.Writable(); + + writable._write = (chunks, encoding, cb) => { + cb(new Error('write test error')); + }; + + writable.on('finish', common.mustCall()); + + writable.on('prefinish', common.mustCall()); + + writable.on('error', common.mustCall((er) => { + assert.strictEqual(er.message, 'write test error'); + })); + + writable.end('test'); +} + +{ + 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', common.mustCall()); + + writable.on('prefinish', common.mustCall()); + + writable.on('error', common.mustCall((er) => { + assert.strictEqual(er.message, 'writev test error'); + })); + + writable.cork(); + writable.write('test'); + + setImmediate(function() { + writable.end('test'); + }); +}