[Bug]: Unhandled promise rejection in fetch().pipe() when response stream errors
- Dominant language
- JavaScript
- Stars
- 45.7k
- Forks
- 1.3k
- PR merge metrics
- No merged PRs in 30d
Description
### What happened?
The `responseToReadable` function in `goods.ts` assigns an async function to `rs._read`, but doesn't wrap it in a try/catch. If `reader.read()` throws (e.g., network disconnection, aborted request, or corrupted stream), the promise rejection is unhandled and can crash the Node.js process.
```typescript
rs._read = async () => {
const result = await reader.read() // Can throw - unhandled
rs.push(result.done ? null : Buffer.from(result.value))
}
```
### How it should work?
Errors from `reader.read()` should be caught and propagated to the stream via `rs.destroy(err)`, allowing downstream consumers to handle the error gracefully.
### How to reproduce the bug?
```javascript
import { fetch } from 'zx'
// Start a fetch that will be aborted mid-stream
const controller = new AbortController()
const result = fetch('https://speed.hetzner.de/100MB.bin', { signal: controller.signal })
const p = result.pipe`cat`
// Abort after a short delay to trigger the error in _read
setTimeout(() => controller.abort(), 100)
await p // Unhandled promise rejection from _read
```
### Version
8.9.0
### What's OS kind?
All
### What JS runtime is used?
Node.js
### Runtime Version
22.x
### Error stack / relevant log output
```shell
UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch()
```
### Code of Conduct
- [x] I agree to follow this project's Code of Conduct
Contributor guide
Assessment
This issue has not been assessed yet.