Skip to content

Commit

Permalink
stream: don't emit 'data' after 'error' or 'close'
Browse files Browse the repository at this point in the history
As per doc we should not emit further events after 'close' and
only 'close' after 'error'.
  • Loading branch information
ronag committed Aug 3, 2021
1 parent f2d02ab commit 701112a
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 1 deletion.
5 changes: 4 additions & 1 deletion lib/internal/streams/readable.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ function readableAddChunk(stream, chunk, encoding, addToFront) {
if (addToFront) {
if (state.endEmitted)
errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT());
else if (state.destroyed || state.errored)
return false;
else
addChunk(stream, state, chunk, true);
} else if (state.ended) {
Expand Down Expand Up @@ -316,6 +318,7 @@ function addChunk(stream, state, chunk, addToFront) {
} else {
state.awaitDrainWriters = null;
}

state.dataEmitted = true;
stream.emit('data', chunk);
} else {
Expand Down Expand Up @@ -542,7 +545,7 @@ Readable.prototype.read = function(n) {
endReadable(this);
}

if (ret !== null) {
if (ret !== null && !state.errorEmitted && !state.closeEmitted) {
state.dataEmitted = true;
this.emit('data', ret);
}
Expand Down
83 changes: 83 additions & 0 deletions test/parallel/test-stream-readable-destroy.js
Original file line number Diff line number Diff line change
Expand Up @@ -319,3 +319,86 @@ const assert = require('assert');
})(), /AbortError/);
setTimeout(() => controller.abort(), 0);
}

{
const read = new Readable({
read() {
},
});
read.push('asd');

read.on('data', common.mustNotCall());
read.on('error', common.mustCall((e) => {
read.read();
}));
read.on('close', common.mustCall((e) => {
read.read();
}));
read.destroy(new Error('asd'));
}

{
const read = new Readable({
read() {
},
});
read.push('asd');

read.on('data', common.mustNotCall());
read.on('close', common.mustCall((e) => {
read.read();
}));
read.destroy();
}

{
const read = new Readable({
read() {
},
});
read.push('asd');

read.on('data', common.mustNotCall());
read.on('close', common.mustCall((e) => {
read.unshift('asd');
}));
read.destroy();
}

{
const read = new Readable({
read() {
},
});
read.push('asd');

read.on('data', common.mustNotCall());
read.destroy();
read.unshift('asd');
}

{
const read = new Readable({
read() {
},
});
read.push('asd');

read.on('data', common.mustNotCall());
read.on('close', common.mustCall((e) => {
read.push('asd');
}));
read.destroy();
}

{
const read = new Readable({
read() {
},
});
read.push('asd');

read.on('data', common.mustNotCall());
read.destroy();
read.push('asd');
}

0 comments on commit 701112a

Please sign in to comment.