-
Notifications
You must be signed in to change notification settings - Fork 161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
.throw()
ing an async iterator
#1284
Comments
const r = new ReadableStream({
pull(c) {
c.enqueue("hello");
},
cancel(arg) {
console.log("cancel", arg);
}
})
for await (const chunk of r) {
throw new Error("errored!");
} This indeed doesn't seem to pass the error object to the cancel callback, I guess a blocking issue is that Web IDL does not define the hook for
Should we have an issue? @MattiasBuelens |
let it = {
[Symbol.iterator]: () => it,
next() {
return { done: false, value: "a" };
},
throw(e) {
console.log("it.throw() called");
return { done: true };
},
return() {
console.log("it.return() called");
return { done: true };
}
};
for (const elem of it) {
throw new Error("boom!");
} The above snippet logs:
So even if we added such a hook, it wouldn't do anything in your example. AFAIK the only built-in construct that interacts with I don't see how we could ever make function* gen() {
while (true) {
try {
yield;
} catch {
continue;
}
}
} But with |
In my iteration utils I have an abort routine that function abort (iterator, error) {
try {
const result = iterator.throw(error)
if (result.done) return
} catch {
return
}
iterator.return(error)
} But this would change the semantics of iterator use right at the core of the language. That would be a big change. I was surprised to see loops don't deliver the error, but then I realized just what you said. It may actually not close the iterator, so you really need the There's that additional complication that |
I guess this would require a whole new error channel in streams. One where the error could be caught and dismissed. const generator = readUsers()
const stream = new ReadableStream({
async catch (error, controller) {
// generator throws in typical case, erroring the stream
const result = await generator.throw(error)
// generator catch block returned, close the stream
if (result.done) await controller.close()
// generator handled the error and resumed, keep the stream open
else return
}
}) |
The
AsyncIterator
spec defines athrow()
method.This method seems to be ignored by streams. The Streams spec defines a response to
return()
but doesn't mentionthrow()
.Implementations have left it out.
web-streams-polyfill
and the Node.js implementation both definereturn()
but notthrow()
. Browsers seem not to support iteration yet.I feel like I should be receiving this signal in my streams. If the consumer has an error, they should be able to tell me so I can respond to it.
One use case:
throw()
is meaningful in a generator function. Suppose I have a series of transforms wrapping a generator. I'd like athrow()
at the end to propagate all the way back so it can be thrown in the generator code. This hits different logic than areturn()
.The error might even be handled so generation can continue. This isn't possible with a
return()
.throw()
is also potentially meaningful in any custom iterators a stream might be wrapping.The text was updated successfully, but these errors were encountered: