stream: don't emit prefinish after error or close

PR-URL: https://github.com/nodejs/node/pull/39332
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Robert Nagy 2021-07-10 00:37:09 +02:00
parent 5960f16713
commit 7a7ba82234
2 changed files with 25 additions and 6 deletions

View File

@ -654,7 +654,9 @@ function needFinish(state) {
!state.errored &&
state.buffered.length === 0 &&
!state.finished &&
!state.writing);
!state.writing &&
!state.errorEmitted &&
!state.closeEmitted);
}
function callFinal(stream, state) {
@ -685,7 +687,7 @@ function callFinal(stream, state) {
then.call(
result,
function() {
if (state.prefinished)
if (state.prefinished || !needFinish(state))
return;
state.prefinish = true;
process.nextTick(() => stream.emit('prefinish'));
@ -735,10 +737,6 @@ function finishMaybe(stream, state, sync) {
function finish(stream, state) {
state.pendingcb--;
// TODO (ronag): Unify with needFinish.
if (state.errorEmitted || state.closeEmitted)
return;
state.finished = true;
const onfinishCallbacks = state[kOnFinished].splice(0);

View File

@ -0,0 +1,21 @@
'use strict';
const common = require('../common');
const { Writable } = require('stream');
{
const w = new Writable({
write(chunk, encoding, callback) {
callback(null);
},
final(callback) {
queueMicrotask(callback);
}
});
w.end();
w.destroy();
w.on('prefinish', common.mustNotCall());
w.on('finish', common.mustNotCall());
w.on('close', common.mustCall());
}