From fa47464fd49fc69008345fdff2a5673c57cf4523 Mon Sep 17 00:00:00 2001 From: wenningplus Date: Mon, 8 Jun 2020 08:07:07 +0800 Subject: [PATCH 1/3] stream: propagate end's cb to write --- lib/_stream_writable.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index 916e9b87d9c17a..685616365dd58c 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -587,7 +587,8 @@ Writable.prototype.end = function(chunk, encoding, cb) { } if (chunk !== null && chunk !== undefined) - this.write(chunk, encoding); + !state.ending ? this.write(chunk, encoding) : + this.write(chunk, encoding, cb); // .end() fully uncorks. if (state.corked) { From 737659b299f74bcf9298a00ad6df095609128da2 Mon Sep 17 00:00:00 2001 From: wenningplus Date: Mon, 8 Jun 2020 13:46:24 +0800 Subject: [PATCH 2/3] stream: add test unit --- lib/_stream_writable.js | 6 +++++- .../test-stream-write-propagate-end-cb.js | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-stream-write-propagate-end-cb.js diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index 685616365dd58c..740e3c298bec83 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -185,6 +185,9 @@ function WritableState(options, stream, isDuplex) { // True if close has been emitted or would have been emitted // depending on emitClose. this.closeEmitted = false; + + // True indicates have invoked error callback + this.invokeError = false; } function resetBuffer(state) { @@ -320,6 +323,7 @@ Writable.prototype.write = function(chunk, encoding, cb) { } if (err) { + this.invokeError = true; process.nextTick(cb, err); errorOrDestroy(this, err, true); return false; @@ -611,7 +615,7 @@ Writable.prototype.end = function(chunk, encoding, cb) { err = new ERR_STREAM_DESTROYED('end'); } - if (typeof cb === 'function') { + if (typeof cb === 'function' && !this.invokeError) { if (err || state.finished) process.nextTick(cb, err); else diff --git a/test/parallel/test-stream-write-propagate-end-cb.js b/test/parallel/test-stream-write-propagate-end-cb.js new file mode 100644 index 00000000000000..2677115cc09b37 --- /dev/null +++ b/test/parallel/test-stream-write-propagate-end-cb.js @@ -0,0 +1,16 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const { Writable } = require('stream'); +{ + const w = new Writable(); + w.end(); + + w.end('asd', (err) => { + assert.strictEqual(err.code, 'ERR_STREAM_WRITE_AFTER_END'); + }); + + w.on('error', (err) => { + assert.strictEqual(err.code, 'ERR_STREAM_WRITE_AFTER_END'); + }); +} From 5d6eafaf6a5b738581d7755bbe9bed853595cca6 Mon Sep 17 00:00:00 2001 From: wenningplus Date: Tue, 9 Jun 2020 17:47:07 +0800 Subject: [PATCH 3/3] test unit using common.mustCall --- test/parallel/test-stream-write-propagate-end-cb.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/parallel/test-stream-write-propagate-end-cb.js b/test/parallel/test-stream-write-propagate-end-cb.js index 2677115cc09b37..eac297218f6a9b 100644 --- a/test/parallel/test-stream-write-propagate-end-cb.js +++ b/test/parallel/test-stream-write-propagate-end-cb.js @@ -1,16 +1,16 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const { Writable } = require('stream'); { const w = new Writable(); w.end(); - w.end('asd', (err) => { + w.end('asd', common.mustCall((err) => { assert.strictEqual(err.code, 'ERR_STREAM_WRITE_AFTER_END'); - }); + })); - w.on('error', (err) => { + w.on('error', common.mustCall((err) => { assert.strictEqual(err.code, 'ERR_STREAM_WRITE_AFTER_END'); - }); + })); }