Skip to content

await for ... on ... catch syntax #1441

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

Open
lukepighetti opened this issue Feb 7, 2021 · 4 comments
Open

await for ... on ... catch syntax #1441

lukepighetti opened this issue Feb 7, 2021 · 4 comments
Labels
feature Proposed language feature that solves one or more problems

Comments

@lukepighetti
Copy link

lukepighetti commented Feb 7, 2021

There is currently no way that I am aware of to handle stream errors in await for loops without breaking the loop.

/// This works, but any error will break the loop and close the subscription
try {
  await for (var e in service.probeEvents()) {
    status = status.copyWith(probes: e);
    yield status;
  }
} on StreamException {
  ///
} catch (e) {
  ///
}

I am proposing that we add syntax on await for as an added feature.

/// Proposing this syntax, where errors will not break the loop
await for (var e in service.probeEvents()) {
  status = status.copyWith(probes: e);
  yield status;
} on StreamException {
  ///
} catch (e) {
  ///
} finally {
  /// onDone
}
@lukepighetti lukepighetti added the feature Proposed language feature that solves one or more problems label Feb 7, 2021
@lrhn
Copy link
Member

lrhn commented Feb 7, 2021

(Edit: Focusing on the issue at hand, instead of getting sidetracked into ideas for other features).

Catching the situation where a stream emits an error in an await for:

await for (var e in stream) {
  body
} on SomeError catch (e) {
  catchBody
}

makes a kind of sense. It corresponds to the onError handler of Stream.listen.

It feels right-ish to me that it comes after the body, but attached to the same loop.

Most streams do not have multiple errors, or errors that are not fatal, but there are some. (Maybe that was a bad idea, but for broadcast streams it felt right). This is not something which is important often, but it is relevant in some cases, and not supported.

Should we also allow finally (for the onDone)? Probably not, it seems like a job for else from #171 instead.

(It's very hard to create errors inside streams using async* syntax because the only way to emit an error is yield*'ing a stream containing an error, like yield* Stream.error(theError);. Maybe, getting sidetracked here, we could let yield e; where e throws emit that error instead of failing. Breaking change, though.)

(Arguably it could also apply to an iterable iteration where the current getter throws.)

@lukepighetti
Copy link
Author

lukepighetti commented Feb 7, 2021

There's a lot to tease out here for new features. One that comes to mind is throw* StreamException, but we don't have to dig into that here I don't think.

finally for onDone would be awesome. It's all upside imho. I like it so much I'm going to add it to the original post.

@PlugFox
Copy link

PlugFox commented Mar 16, 2021

@lukepighetti check this sample)

https://dartpad.dev/1b73d1115f3c8de0ca70872f70ad9d95?null_safety=true

@lukepighetti
Copy link
Author

What am I looking for?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Proposed language feature that solves one or more problems
Projects
None yet
Development

No branches or pull requests

3 participants