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 +};