Open
Description
Version
22.12.0
Platform
Microsoft Windows NT 10.0.26100.0
x64
Subsystem
No response
What steps will reproduce the bug?
Suppose downloading a large file using fetch API.
When the response stream is being read and abort the fetch request afterwards, it will throw a uncatchable exception and crash the process.
import { Readable } from "stream";
import { finished } from "stream/promises";
import fs from "fs";
try {
const res = await fetch("https://testfile.org/1.3GBiconpng", {
signal: AbortSignal.timeout(5000),
});
const fileStream = fs.createWriteStream("./test");
await finished(Readable.fromWeb(res.body).pipe(fileStream));
} catch (err) {
// Cannot catch the abort error
console.error("Error occurred!", err);
}
How often does it reproduce? Is there a required condition?
Always.
What is the expected behavior? Why is that the expected behavior?
Error should be caught.
What do you see instead?
Uncaught exception is thrown. Process crashes.
node:events:502
throw er; // Unhandled 'error' event
^
DOMException [TimeoutError]: The operation was aborted due to timeout
at new DOMException (node:internal/per_context/domexception:53:5)
at Timeout._onTimeout (node:internal/abort_controller:141:9)
at listOnTimeout (node:internal/timers:594:17)
at process.processTimers (node:internal/timers:529:7)
Emitted 'error' event on Readable instance at:
at emitErrorNT (node:internal/streams/destroy:170:8)
at emitErrorCloseNT (node:internal/streams/destroy:129:3)
at process.processTicksAndRejections (node:internal/process/task_queues:90:21)
Additional information
If you want to set a timeout for the fetch request in this case, you should use setTimeout and AbortController manually.
import { Readable } from "stream";
import { finished } from "stream/promises";
import fs from "fs";
const controller = new AbortController();
const id = setTimeout(() => {
controller.abort();
}, 5000);
try {
const res = await fetch("https://testfile.org/1.3GBiconpng", {
signal: controller.signal,
});
clearTimeout(id);
const fileStream = fs.createWriteStream("./test");
await finished(Readable.fromWeb(res.body).pipe(fileStream));
} catch (err) {
console.error("Error occurred!", err);
}
Metadata
Metadata
Assignees
Labels
No labels