Proposal: Operator to "demote" checked exceptions
negora
public at negora.com
Wed Mar 16 09:12:29 UTC 2022
Hi Brian. Thank you for your answer and apologizes for the delay.
I must admit that, in a first stage of my proposal, my idea was about
adding some syntactic sugar to wrap/unwrap exceptions easily, without
the need of try-catch blocks. But that led me to the idea of removing
the need of wrapping altogether and, hence, propose the feature of
switchable checked exceptions.
My initial proposal looked like this:
```
public Student parseStudent (String line)
throws StudentException
wraps IOException, ParseException {
// Code.
}
```
Instead of this:
```
public Student parseStudent (String line) {
try {
// Code.
} catch (IOException | ParseException ex) {
throw new StudentException (ex);
}
}
```
Obviously, the wrapper exception should provide at least
one constructor with a single parameter of type `Throwable`.
And the signature of the method would not include
the `wraps` clause.
Maybe it's just me, but try-catch blocks introduce visual
complexity that distracts me while reading the body of a method.
It could be alleviated **a lot** with this.
From my experience, many try-catch blocks are just
to wrap checked exceptions between abstraction layers,
so this would be very helpful in many parts of our code bases.
In practice, the use of try-catch blocks would be reduced
to those situations in which we need to do something
different from just wrapping an exception.
In contrast to the proposal of switchable exceptions, this
syntax couldn't be directly applied to lambdas. But at least
one could extract the code to a new method and keep it cleaner
that with a try-catch.
> One context that could become pattern-aware is catch. And
> deconstruction patterns compose, so we could give exceptions
> deconstruction patterns to match their wrapping constructors, so that
> you could say
>
> catch (RuntimeException(SqlException se)) { … }
>
> which reduces the syntactic overhead of unwrapping to basically
> zero.
That sounds interesting. But, Could the opposite concept be carried
to the `throws` clause? I mean, a construction pattern
instead of a deconstruction one. Something similar to
my first example, but without the need of a new keyword:
```
public Student parseStudent (String line)
throws StudentException (IOException | ParseException) {
// Code.
}
```
I really prefer the use of the `wraps` keyword, but I understand
that introducing a new keyword has lots of side-effects.
On 07/03/2022 21:38, Brian Goetz wrote:
> Not going to engage on the “should we give people the opportunity to turn off checked exceptions”, but I will make a few comments on how we might reduce the accidental cost of wrapping and unwrapping exceptions.
>
>> 3. If you want to rethrow the original exceptions, you're forced to catch the wrapper first, and then analyse and downcast the wrapped exceptions.
>
> We’re in the process of adding pattern matching to the language, in stages. Currently patterns are restricted to type patterns, and pattern-aware contexts are restricted to instanceof and switch, but both categories will expand over time.
>
> One context that could become pattern-aware is catch. And deconstruction patterns compose, so we could give exceptions deconstruction patterns to match their wrapping constructors, so that you could say
>
> catch (RuntimeException(SqlException se)) { … }
>
> which reduces the syntactic overhead of unwrapping to basically zero. I’m much more compelled by directions like this, which embrace the tools we have, but reduce their accidental impact. (Obviously there’s work to do to make everything about wrapping this smooth.)
More information about the amber-dev
mailing list