On Wed, Mar 30, 2022 at 2:38 PM Brian Goetz <brian.go...@oracle.com> wrote:
>
> Another way to think about this is:
>
>  - If any of the code that the user actually wrote (the RHS of case clauses, 
> or guards on case labels) throws, then the switch throws that
>  - If any of the machinery of the switch dispatch throws, it throws 
> MatchException.
>

That's a reasonable way to factor this and makes the difference
between the machinery and the direct user code clear, even when
looking at stacktraces.

And from your other response:

> Another thing it gains is that it discourages people
> from thinking they can use exceptions in dtors; having these laundered
> through MatchException discourages using this as a side channel, though
> that's a more minor thing.

This is a stronger argument than you give it credit for being.
Wrapping the exception adds a bit of friction to doing the wrong thing
which will pay off in helping guide users to the intended behaviour.

--Dan

> On 3/30/2022 2:12 PM, Dan Heidinga wrote:
>
> The rules regarding NPE, ICCE and MatchException look reasonable to me.
>
>
> As a separate but not-separate exception problem, we have to deal with at 
> least two additional sources of exceptions:
>
>  - A dtor / record acessor may throw an arbitrary exception in the course of 
> evaluating whether a case matches.
>
>  - User code in the switch may throw an arbitrary exception.
>
> For the latter, this has always been handled by having the switch terminate 
> abruptly with the same exception, and we should continue to do this.
>
> For the former, we surely do not want to swallow this exception (such an 
> exception indicates a bug).  The choices here are to treat this the same way 
> we do with user code, throwing it out of the switch, or to wrap with 
> MatchException.
>
> I prefer the latter -- wrapping with MatchException -- because the exception 
> is thrown from synthetic code between the user code and the ultimate thrower, 
> which means the pattern matching feature is mediating access to the thrower.  
> I think we should handle this as "if a pattern invoked from pattern matching 
> completes abruptly by throwing X, pattern matching completes abruptly with 
> MatchException", because the specific X is not a detail we want the user to 
> bind to.  (We don't want them to bind to anything, but if they do, we want 
> them to bind to the logical action, not the implementation details.)
>
> My intuition (and maybe I have the wrong mental model?) is that the
> pattern matching calling a user written dtor / record accessor is akin
> to calling a method.  We don't wrap the exceptions thrown by methods
> apart from some very narrow cases (ie: reflection), and I thought part
> of reflection's behaviour was related to needing to ensure exceptions
> (particularly checked ones) were converted to something explicitly
> handled by the caller.
>
> If the dtor / record accessor can declare they throw checked
> exceptions, then I can kind of see the rationale for wrapping them.
> Otherwise, it seems clearer to me to let them be thrown without
> wrapping.
>
> I don't think we expect users to explicitly handle MatchException when
> using pattern matching so what does wrapping gain us here?
>
> --Dan
>
>

Reply via email to