I believe the issue with checked exceptions in Java are multi-fold.

First, there are both checked and unchecked exceptions, which gives developers 
a way to avoid checked exceptions completely. RuntimeException is unchecked and 
meant to handle runtime detectable issues like math overflow or arrays indexed 
out of bounds, which would be too unwieldy for developers to have to catch 
explicitly - especially when they may “know” that an expression like "1 + 1" 
will not overflow. In Swift, many of these issues actually result in a fatal 
error.

RuntimeExceptions are also used extensively to work around cases where the 
appropriate checked exception is not defined on an interface or superclass. In 
these cases you cannot expand the list of checked exceptions declared, but you 
still want to throw on error. In this case, you wrap your desired exception in 
a RuntimeException, or just throw your hands up in the air and throw a 
RuntimeException with a string description. With such a large escape hatch from 
checked exceptions, the verbosity of doing things “the correct way” becomes a 
much more obvious burden.

Java does not have pattern matching in exceptions, with built-in support only 
for switching on class type of caught exception. However, many modules outside 
the very core of the language declare a single module-level exception, e.g. 
AWTException. This means there is an impedance mismatch - the declaration of 
exception types does not map well always to the appropriate recovery mechanism 
from the exception.

Having checked exceptions makes it more likely that interfaces will not be 
declared throwing, as the interface creator may not know the appropriate types 
of exceptions to be declared.

An interface expected to return an object might get the object from the 
network, filesystem,. or a database - resulting in three different families of 
possible exception types. This is usually worked around by having a 
module-level exception that is declared as the checked type, which can hold the 
actual exception which happened. Because the module-level exceptions do not 
differentiate classifications of issues, and the implementation of the 
interface does not have the actual kind of exception as part of the interface 
contract, you are limited in your ability to handle the exception in your code. 
It becomes commonplace to have a single “that thing you tried to do failed”, 
with a long stack trace to enable a developer or someone in a supporting role 
to diagnose which code was involved in the failure.



This gets to the root of the problem - since the focus is on documenting the 
class types of exceptions rather than categories of error states, the developer 
doesn’t feel any of the complexity or verbosity helps them make their code more 
robust. Instead of considering how to represent errors to your own callers for 
recovery, it becomes common to just declare the same list of checked exceptions 
and pass them through upstream unhanded - or to wrap them all in a module-level 
exception type to simplify the interface. The end result is that the exception 
mechanism is made more heavyweight via the checked mechanism, but still doesn’t 
enable developers to make their code more robust.

In the end, I believe the thing to emphasize is that developers of an API need 
to think of how the errors they raise would be handled by potential callers, 
and to represent *that* in their API. This might result in a specific error 
enumeration per method, which is O.K. In that case, declaring such a thrown 
error so that the error cases may be handled exhaustively is probably a good 
thing. A declaration which either does not allow exhaustive handling of error 
cases, or which allows someone to forward errors from multiple sources without 
thinking about their caller’s error needs are probably not productive.

-DW

> On Aug 26, 2016, at 10:01 AM, Nur Ismail via swift-evolution 
> <[email protected]> wrote:
> 
> Hi,
> 
> Sounds like checked exceptions of Java with a similar syntax. With Java you 
> have to specify the exceptions a method can throw. However been lots of 
> debate over the years whether it's a good thing or bad thing, some like it, 
> but I think many more hate it.
> Most other languages don't have it, and possibly for good reason.
> 
> Regards,
> 
> On Fri, Aug 26, 2016 at 5:43 PM, Rod Brown via swift-evolution 
> <[email protected] <mailto:[email protected]>> wrote:
> (resent for Swift Evolution)
> 
> I’m a big fan of this idea. Currently “throws” seems like a very limited API 
> - you know it’s throwing out something, but you can only hope to guess what 
> that is or create fallbacks. Definitely a big +1 from me. A fallback for 
> compatibility could be “throws” assumes “throws Any” and can be a warning?
> 
> While I am not deeply familiar with the implications, I do like think your 
> line of reasoning has merit, and think this makes sense for Phase 1 of Swift 
> 4. 
> 
> - Rod
> 
> 
>> On 27 Aug 2016, at 1:39 AM, Félix Cloutier via swift-evolution 
>> <[email protected] <mailto:[email protected]>> wrote:
>> 
>> Hi all,
>> 
>> Currently, a function that throws is assumed to throw anything. There was a 
>> proposal draft last December to restrict that. The general idea was that 
>> you'd write, for instance:
>> 
>>> enum Foo: ErrorProtocol {
>>>     case bar
>>>     case baz
>>> }
>>> 
>>> func frob() throws Foo {
>>>     throw Foo.bar // throw .bar?
>>> }
>> 
>> If you `catch Foo` (or every case of Foo), now that the compiler can verify 
>> that your catch is exhaustive, you no longer have to have a catch-all block 
>> at the end of the sequence.
>> 
>> This impacts the metadata format and has implications on resilience, which 
>> leads me to believe that the discussion could qualify for the phase 1 of 
>> Swift 4. If this is the case, I'd be interested in pulling out the old 
>> discussions and seeing where we left that at.
>> 
>> Félix
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> 
> _______________________________________________
> swift-evolution mailing list
> [email protected] <mailto:[email protected]>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> 
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to