mirror of
https://github.com/nodejs/node.git
synced 2026-11-09 15:11:11 -05:00
stream: fix async iterator destroyed error propagation
There was an edge case where if _destroy calls the error callback later than one tick the iterator would complete early and not propgate the error. PR-URL: https://github.com/nodejs/node/pull/31314 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Minwoo Jung <nodecorelab@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
1 parent
eb5e1ddd31
commit
d15b8ea3bd
2 files changed
+30
-11
No files matched your search
@@ -78,18 +78,20 @@ const ReadableStreamAsyncIteratorPrototype = ObjectSetPrototypeOf({
|
||||
}
|
||||
|
||||
if (this[kStream].destroyed) {
|
||||
// We need to defer via nextTick because if .destroy(err) is
|
||||
// called, the error will be emitted via nextTick, and
|
||||
// we cannot guarantee that there is no error lingering around
|
||||
// waiting to be emitted.
|
||||
return new Promise((resolve, reject) => {
|
||||
process.nextTick(() => {
|
||||
if (this[kError]) {
|
||||
reject(this[kError]);
|
||||
} else {
|
||||
resolve(createIterResult(undefined, true));
|
||||
}
|
||||
});
|
||||
if (this[kError]) {
|
||||
reject(this[kError]);
|
||||
} else if (this[kEnded]) {
|
||||
resolve(createIterResult(undefined, true));
|
||||
} else {
|
||||
finished(this[kStream], (err) => {
|
||||
if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(createIterResult(undefined, true));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -484,6 +484,23 @@ async function tests() {
|
||||
assert.strictEqual(e, err);
|
||||
})()]);
|
||||
}
|
||||
|
||||
{
|
||||
const _err = new Error('asd');
|
||||
const r = new Readable({
|
||||
read() {
|
||||
},
|
||||
destroy(err, callback) {
|
||||
setTimeout(() => callback(_err), 1);
|
||||
}
|
||||
});
|
||||
|
||||
r.destroy();
|
||||
const it = r[Symbol.asyncIterator]();
|
||||
it.next().catch(common.mustCall((err) => {
|
||||
assert.strictEqual(err, _err);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user