From f8e42d24fc3f65e9239d4851e3ae10871d61f167 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Wed, 10 Nov 2021 10:14:48 +0200 Subject: [PATCH 1/4] stream: allow calling callback before promise Refs: https://github.com/nodejs/node/issues/39535 --- lib/internal/streams/destroy.js | 8 ++++++-- lib/internal/streams/writable.js | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/internal/streams/destroy.js b/lib/internal/streams/destroy.js index 7d3657443e6ab5..efa09e05eafef0 100644 --- a/lib/internal/streams/destroy.js +++ b/lib/internal/streams/destroy.js @@ -292,10 +292,14 @@ function constructNT(stream) { then.call( result, function() { - process.nextTick(onConstruct, null); + if (!called) { + process.nextTick(onConstruct, null); + } }, function(err) { - process.nextTick(onConstruct, err); + if (!called) { + process.nextTick(onConstruct, err); + } }); } } diff --git a/lib/internal/streams/writable.js b/lib/internal/streams/writable.js index 727e7ede71f8aa..38bfea52a15bfd 100644 --- a/lib/internal/streams/writable.js +++ b/lib/internal/streams/writable.js @@ -699,10 +699,14 @@ function callFinal(stream, state) { then.call( result, function() { - process.nextTick(onFinish, null); + if (!called) { + process.nextTick(onFinish, null); + } }, function(err) { - process.nextTick(onFinish, err); + if (!called) { + process.nextTick(onFinish, err); + } }); } } From 6d1bbf7256b61a0ce2a2b9b63a6802e53376e77d Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Wed, 10 Nov 2021 10:16:52 +0200 Subject: [PATCH 2/4] fixup --- lib/internal/streams/transform.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/internal/streams/transform.js b/lib/internal/streams/transform.js index 26e0b07c2956c8..397daa38efac2d 100644 --- a/lib/internal/streams/transform.js +++ b/lib/internal/streams/transform.js @@ -228,7 +228,9 @@ Transform.prototype._write = function(chunk, encoding, callback) { } }, (err) => { - process.nextTick(callback, err); + if (!called) { + process.nextTick(callback, err); + } }); } } catch (err) { From 32f0dfaa58c5f0015281c6fcf754208dd3d25b68 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Wed, 10 Nov 2021 10:41:01 +0200 Subject: [PATCH 3/4] fixup --- lib/internal/streams/transform.js | 4 +-- .../test-stream-construct-async-error.js | 24 +--------------- .../test-stream-writable-final-async.js | 28 +++++++++++++++++++ 3 files changed, 30 insertions(+), 26 deletions(-) create mode 100644 test/parallel/test-stream-writable-final-async.js diff --git a/lib/internal/streams/transform.js b/lib/internal/streams/transform.js index 397daa38efac2d..26e0b07c2956c8 100644 --- a/lib/internal/streams/transform.js +++ b/lib/internal/streams/transform.js @@ -228,9 +228,7 @@ Transform.prototype._write = function(chunk, encoding, callback) { } }, (err) => { - if (!called) { - process.nextTick(callback, err); - } + process.nextTick(callback, err); }); } } catch (err) { diff --git a/test/parallel/test-stream-construct-async-error.js b/test/parallel/test-stream-construct-async-error.js index 8101ec93fc0d74..c8ca293f1b08e3 100644 --- a/test/parallel/test-stream-construct-async-error.js +++ b/test/parallel/test-stream-construct-async-error.js @@ -9,26 +9,6 @@ const { const { setTimeout } = require('timers/promises'); const assert = require('assert'); -{ - class Foo extends Duplex { - async _construct(cb) { - // eslint-disable-next-line no-restricted-syntax - await setTimeout(common.platformTimeout(1)); - cb(); - throw new Error('boom'); - } - } - - const foo = new Foo(); - foo.on('error', common.expectsError({ - message: 'boom' - })); - foo.on('close', common.mustCall(() => { - assert(foo._writableState.constructed); - assert(foo._readableState.constructed); - })); -} - { class Foo extends Duplex { async _destroy(err, cb) { @@ -98,9 +78,7 @@ const assert = require('assert'); const foo = new Foo(); foo.write('test', common.mustCall()); - foo.on('error', common.expectsError({ - code: 'ERR_MULTIPLE_CALLBACK' - })); + foo.on('error', common.mustNotCall()); } { diff --git a/test/parallel/test-stream-writable-final-async.js b/test/parallel/test-stream-writable-final-async.js new file mode 100644 index 00000000000000..08c25ec7d9d02d --- /dev/null +++ b/test/parallel/test-stream-writable-final-async.js @@ -0,0 +1,28 @@ +'use strict'; + +const common = require('../common'); +const { + Duplex, +} = require('stream'); +const { setTimeout } = require('timers/promises'); +const assert = require('assert'); + +{ + class Foo extends Duplex { + async _final(callback) { + // eslint-disable-next-line no-restricted-syntax + await setTimeout(common.platformTimeout(1)); + callback(); + } + + _write = common.mustCall((chunk, encoding, cb) => { + cb(); + }) + + _read() {} + } + + const foo = new Foo(); + foo.end('test', common.mustCall()); + foo.on('error', common.mustNotCall()); +} From 7d2486ac416da70873bea1d4baf0182f58e3fdf0 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Wed, 10 Nov 2021 11:14:40 +0200 Subject: [PATCH 4/4] fixup --- test/parallel/test-stream-writable-final-async.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/test/parallel/test-stream-writable-final-async.js b/test/parallel/test-stream-writable-final-async.js index 08c25ec7d9d02d..5571b794fd4fbd 100644 --- a/test/parallel/test-stream-writable-final-async.js +++ b/test/parallel/test-stream-writable-final-async.js @@ -5,7 +5,6 @@ const { Duplex, } = require('stream'); const { setTimeout } = require('timers/promises'); -const assert = require('assert'); { class Foo extends Duplex { @@ -15,14 +14,13 @@ const assert = require('assert'); callback(); } - _write = common.mustCall((chunk, encoding, cb) => { - cb(); - }) - _read() {} } const foo = new Foo(); + foo._write = common.mustCall((chunk, encoding, cb) => { + cb(); + }); foo.end('test', common.mustCall()); foo.on('error', common.mustNotCall()); }