Skip to content

Instantly share code, notes, and snippets.

@SgtPooki
Created November 10, 2025 14:45
Show Gist options
  • Select an option

  • Save SgtPooki/5a3fe6ab95c5c340039ce32360829833 to your computer and use it in GitHub Desktop.

Select an option

Save SgtPooki/5a3fe6ab95c5c340039ce32360829833 to your computer and use it in GitHub Desktop.
readableStream controller.error not calling cancel
async function* makeGenerator() {
try {
let i = 0
while (true) {
yield i++
await new Promise(r => setTimeout(r, 10))
}
} finally {
console.log(">>> GENERATOR CLEANED UP (finally ran)")
}
}
const iterable = makeGenerator()
const iterator = iterable[Symbol.asyncIterator]()
const stream = new ReadableStream({
async pull(controller) {
const { value } = await iterator.next()
controller.enqueue(value)
if (value === 3) {
console.log(">>> ERRORING STREAM (controller.error)")
controller.error(new Error("boom"))
// NOTE: unless we do the below, generator finally does not run
try { if (iterator.return) { await iterator.return() } } catch {}
}
},
async cancel() {
console.log(">>> STREAM CANCELED (cancel called)")
if (iterator.return) {
await iterator.return()
}
}
})
const reader = stream.getReader()
// consume until error
try {
while (true) {
const { value } = await reader.read()
console.log("read:", value)
}
} catch (e) {
console.log("caught:", e.message)
}
// wait briefly so any finally could run if it were going to
await new Promise(r => setTimeout(r, 50))
console.log(">>> DONE")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment