[swift-evolution] Type-annotated throws

Russ Bishop xenadu at gmail.com
Mon Aug 29 23:13:51 CDT 2016

> On Aug 26, 2016, at 8:39 AM, Félix Cloutier via swift-evolution <swift-evolution at swift.org> 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 contract is a lie in almost all real-world programs because real programs talk to the network, the filesystem, the database, etc and the class of errors that can be thrown is tremendous. The number of functions where “throws Foo” is an improvement and Foo is not an exhaustive list of “throws HTTPError, NetworkError, StorageError, DatabaseError, MachPortError, …” is close enough to zero to be considered zero. This ultimately leads to library authors merely wrapping exceptions using generic catch-all blocks anyway, adding no useful information.

There is zero value to adding it without the compiler enforcing it because you can only omit default catch blocks safely when you can be certain the list of exceptions is exhaustive.

I am sympathetic to the default/generic catch block problem but we could certainly solve that with some added syntax or automatic insertion of a rethrow if an error doesn’t match, meaning any function with a try{} and no default catch must itself be a throwing function.

Since this isn’t applicable to Swift 4 phase 1 I’ll hush now :)


More information about the swift-evolution mailing list