Skip to content
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

Syntax catching multiple exceptions in a single on block #112

Open
jonasfj opened this issue Nov 28, 2018 · 9 comments
Open

Syntax catching multiple exceptions in a single on block #112

jonasfj opened this issue Nov 28, 2018 · 9 comments
Labels
request Requests to resolve a particular developer problem

Comments

@jonasfj
Copy link
Member

jonasfj commented Nov 28, 2018

In many cases I only care what type of exception I'm getting.
I don't care about the exception at-most I might want to do a e.toString().

Example:

for (int i = 0; i < retries; i++) {
  try {
    return networkOperation().timeout(Duration(seconds: 5));
  } on SocketException, TimeoutException {
    continue;
  }
}

This isn't critical at all, I was just surprised it didn't work already.

It's trivial to duplicate the block handling the exception, or write a function that accepts a list of types to ignore.

Please close if there is some complication to this that I don't see :)

@mit-mit mit-mit added the request Requests to resolve a particular developer problem label Nov 30, 2018
@jaumard
Copy link

jaumard commented Dec 6, 2018

Being able to catch multiple exception in one block is really useful in my opinion to avoid duplication of code or noise on error management

@munificent
Copy link
Member

If you look at this more generally, a catch clause:

  • Tests an object against some type (the on clause).
  • If the object has that type, optionally bind a new variable for the object (the catch clause).
  • Conditional executes some code where that variable is in scope (the catch block).

That's really similar to how pattern matching works in languages that have that. Most of those languages have some kind of | pattern that lets you concatenate multiple patterns together.

We're considering adding tuples to Dart, and those almost always lead to some kind of pattern matching syntax in order to destructure the fields back out of the tuple. If we do that, one solution for the problem here would be to extend to catch clauses to allow arbitrary patterns. If we have some kind of "or" pattern, that would then let you have a single catch clause that matches objects of multiple types.

@lrhn lrhn added small-feature A small feature which is relatively cheap to implement. and removed small-feature A small feature which is relatively cheap to implement. labels Jul 8, 2020
@omidraha
Copy link

omidraha commented Aug 1, 2020

Related link.

@lrhn
Copy link
Member

lrhn commented Dec 18, 2020

One issue with allowing multiple on types is that it makes it harder to type the catch (e) variable.
We can either disallow having a catch clause if you have more than one on type, or we can find some least upper bound of the on types to use for the e variable. (A general least upper bound function in an interface based language isn't well-defined, there might not be one least upper bound.) We definitely don't want to introduce union types for this.

@natebosch
Copy link
Member

or we can find some least upper bound of the on types to use for the e variable.

I think that would feel comfortable for most authors since we hit it with other patterns too.

@marianhlavac
Copy link

disallow having a catch clause if you have more than one on type

That seems like a reasonable tradeoff.

Any progress on this language feature? It seems that the discussion is already dead.

@munificent
Copy link
Member

Any progress on this language feature? It seems that the discussion is already dead.

No progress (it's not a particularly burning issue), but we are working on pattern matching again, it's possible that we'll incorporate some pattern stuff into on clauses, which might cover this use case. No promises, because, again, it's not a super high priority, but it would be nice.

@jamesderlin
Copy link

jamesderlin commented May 25, 2022

One issue with allowing multiple on types is that it makes it harder to type the catch (e) variable. We can either disallow having a catch clause if you have more than one on type, or we can find some least upper bound of the on types to use for the e variable. (A general least upper bound function in an interface based language isn't well-defined, there might not be one least upper bound.) We definitely don't want to introduce union types for this.

Could something like:

try {
  doSomething();
} on ExceptionA, ExceptionB catch (e) {
  fail(e);
}

be syntactic sugar for:

try {
  doSomething();
} catch (e) {
  if (e is ExceptionA || e is ExceptionB) {
    fail(e);
  } else {
    rethrow;
  }
}

? In the above case, e is already determined to be a common base type of ExceptionA and ExceptionB.

Edit:
Ignore me, I am wrong. I accidentally did on Exception catch (e) { ... } when I tried it and then mistook e's type as Exception to be the common base type.

@Jetz72
Copy link

Jetz72 commented May 25, 2022

Perhaps you could leave it to the user to specify their preferred common parent for the variable when they name it in the catch clause, if there's more than one type in the on clause. E.g. on ExceptionA, ExceptionB catch(Exception e) {. All types in the on clause would need to be subtypes of whichever type is specified in the catch clause. Leaving the type out could default to Object.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
request Requests to resolve a particular developer problem
Projects
None yet
Development

No branches or pull requests

10 participants