From 3e7199e577362f8a29b4081ca6320c3f3368a418 Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Wed, 21 Jun 2017 23:07:52 +0200 Subject: [PATCH] Forward-port of nodejs#13850 https://github.com/nodejs/node/pull/13850 --- lib/_stream_writable.js | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index a438f213dd..ad38c6aa8d 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -408,15 +408,26 @@ function doWrite(stream, state, writev, len, chunk, encoding, cb) { function onwriteError(stream, state, sync, er, cb) { --state.pendingcb; - if (sync) processNextTick(afterError, stream, state, cb, er);else afterError(stream, state, cb, er); - stream._writableState.errorEmitted = true; - stream.emit('error', er); -} - -function afterError(stream, state, cb, err) { - cb(err); - finishMaybe(stream, state); + if (sync) { + // defer the callback if we are being called synchronously + // to avoid piling up things on the stack + processNextTick(cb, er); + // this can emit finish, and it will always happen + // after error + processNextTick(finishMaybe, stream, state); + stream._writableState.errorEmitted = true; + stream.emit('error', er); + } else { + // the caller expect this to happen before if + // it is async + cb(er); + stream._writableState.errorEmitted = true; + stream.emit('error', er); + // this can emit finish, but finish must + // always follow error + finishMaybe(stream, state); + } } function onwriteStateUpdate(state) { @@ -649,4 +660,4 @@ Writable.prototype._undestroy = destroyImpl.undestroy; Writable.prototype._destroy = function (err, cb) { this.end(); cb(err); -}; \ No newline at end of file +};