Swift: `throws` keyword annotated with types

Originator:dennis
Number:rdar://22870806 Date Originated:26-Sep-2015
Status:Open Resolved:
Product:Developer Tools Product Version:
Classification:Enhancement Reproducible:N/A
 
I love the work the Swift team has done. Swift is one of the closest languages to being perfect that I see out there right now (maybe it's the novelty). But I think that this particular language feature--the forced general throwing annotations--puts a major stopper in the attempts of myself and countless other programmers attempting to write code the way it is intended to be written. Whenever I use a throwing function I find myself doing something like this:

```do {
  let result = try searchForQuery(query) // function I wrote, it only ever throws an error of type `SearchError`
} catch let error as SearchError {
  // do something helpful with the error, because I know its type
} catch let error {
  // this is required by the compiler for completeness. But it confuses me a bit.
  // On the one hand, it feels wrong to swallow because, since throws is not typed, a teammate could just change my function to throw a different type of error without remembering to add handling code here. But what am I supposed to do with this error? Literally all I know about it is that it conforms to ErrorType. So maybe I should just swallow it.
  // Regardless, this section is, at best, useless, and at worst, dangerous to error handling.
}```

99% of the time I know what kind of error I am going to throw. The other 1%, I should either figure out which error I'm going to throw, or use `rethrows` instead. (In this situation, I think it would be prudent to keep `rethrows` generic, unless you decide you want developers to type-annotate the throwing closures they pass into a rethrowing function, which would also make sense.)


Some caveats/benefits if you decide to move forward with this proposal:
- I would consider it part of the base functionality to be able to annotate with multiple ErrorTypes. Something like `func searchForQuery(query: String) throws SearchError, NetworkError -> [Item]` or `func searchForQuery(query: String) -> [Item] throws SearchError, NetworkError`.

- One other potential benefit of type-annotating `throws` would be that you could provide intelligent autocompletion for `catch` statements, since you would be able to statically collect the potential ErrorTypes that can be thrown by each throwing expression in the `do` block. 

- To migrate from existing swift code... One way would be to assume `throws` is equivalent `throws ErrorType` and add a compiler warning to anything that is marked with just `throws` implicitly with a suggested auto-fix that either replaces `throws` with `throws ErrorType` or statically analyzes the function's body to see what it throws at each `try`/`throw` statement (probably not in the scope of this feature, realistically). Another way would be to just stick a compiler error on every instance of a naked `throws` saying "Needs to throw one or more types that implements ErrorType", and have a suggested auto-fix similar to the first way I described.
- In the vein of the previous bullet point, I will warn that it may be disingenuous to have a code style migrator like you had for the transition to Swift 2. An automatic migration would encourage people not to put thought into reannotating their existing throwing code. Personally, I think the best option would be the compiler warning I described with no code migration helper.

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!