diff --git a/lib/internal/streams/destroy.js b/lib/internal/streams/destroy.js index 985332ac4607a8..a418a49523900d 100644 --- a/lib/internal/streams/destroy.js +++ b/lib/internal/streams/destroy.js @@ -10,10 +10,15 @@ function destroy(err, cb) { if (readableDestroyed || writableDestroyed) { if (cb) { cb(err); - } else if (err && - (!this._writableState || !this._writableState.errorEmitted)) { - process.nextTick(emitErrorNT, this, err); + } else if (err) { + if (!this._writableState) { + process.nextTick(emitErrorNT, this, err); + } else if (!this._writableState.errorEmitted) { + this._writableState.errorEmitted = true; + process.nextTick(emitErrorNT, this, err); + } } + return this; } @@ -31,9 +36,11 @@ function destroy(err, cb) { this._destroy(err || null, (err) => { if (!cb && err) { - process.nextTick(emitErrorNT, this, err); - if (this._writableState) { + if (!this._writableState) { + process.nextTick(emitErrorNT, this, err); + } else if (!this._writableState.errorEmitted) { this._writableState.errorEmitted = true; + process.nextTick(emitErrorNT, this, err); } } else if (cb) { cb(err); diff --git a/test/parallel/test-stream-writable-destroy.js b/test/parallel/test-stream-writable-destroy.js index 46c48511177813..2d5ad8e6b9e189 100644 --- a/test/parallel/test-stream-writable-destroy.js +++ b/test/parallel/test-stream-writable-destroy.js @@ -146,6 +146,32 @@ const { inherits } = require('util'); assert.strictEqual(write.destroyed, true); } +{ + const writable = new Writable({ + destroy: common.mustCall(function(err, cb) { + process.nextTick(cb, new Error('kaboom 1')); + }), + write(chunk, enc, cb) { + cb(); + } + }); + + writable.on('close', common.mustNotCall()); + writable.on('error', common.expectsError({ + type: Error, + message: 'kaboom 2' + })); + + writable.destroy(); + assert.strictEqual(writable.destroyed, true); + assert.strictEqual(writable._writableState.errorEmitted, false); + + // Test case where `writable.destroy()` is called again with an error before + // the `_destroy()` callback is called. + writable.destroy(new Error('kaboom 2')); + assert.strictEqual(writable._writableState.errorEmitted, true); +} + { const write = new Writable({ write(chunk, enc, cb) { cb(); }