Closed
Description
- Version: v10.12.0
- Platform: Windows 10 64-bits
- Subsystem: streams
Async iteration over a readable stream breaks horribly if for any reason the stream is destroyed while the iteration is still running (or even if it is destroyed before starting the iteration). I would expect that the iteration runs normally or throws an exception. What happens instead is that the whole event loop is shut down.
Most notably this makes async iteration useless with pipeline
.
Test code:
const {createReadStream} = require('fs');
const {pipeline} = require('stream');
const {createDeflate} = require('zlib');
async function iterate(name, stream, destroy = false) {
try {
console.log(`${name}: Starting loop`);
for await (const chunk of stream) {
console.log(`${name}: Got a chunk`);
if (destroy) {
console.log(`${name}: destroying stream`);
stream.destroy();
}
}
console.log(`${name}: loop ended`);
} catch (err) {
console.log(`${name}: loop ended with error: ${err}`);
}
}
async function main() {
// These work fine
await iterate('oneStream', createReadStream('test.js'));
await iterate('oneStreamError', createReadStream('doesnotexist'));
// Any of these just shuts down the node event loop...
await iterate('oneStreamDestroy', createReadStream('test.js'), true);
await iterate('pipeline', pipeline(createReadStream('doesnotexist'), createDeflate(), err => console.log(`pipeline ended: ${err}`)));
const stream = createReadStream('test.js');
stream.destroy();
await iterate('destroyedStream', stream);
}
main().catch(console.error);
Output:
> node test.js
oneStream: Starting loop
(node:21664) ExperimentalWarning: Readable[Symbol.asyncIterator] is an experimental feature. This feature could change at any time
oneStream: Got a chunk
oneStream: loop ended
oneStreamError: Starting loop
oneStreamError: loop ended with error: Error: ENOENT: no such file or directory, open 'C:\Users\mfischer\src\tests\node-stream-async-iteration\doesnotexist'
oneStreamDestroy: Starting loop
oneStreamDestroy: Got a chunk
oneStreamDestroy: destroying stream