[swift-evolution] Swift error handling suggestion

Paweł Wojtkowiak neframair at gmail.com
Thu Mar 2 02:14:51 CST 2017


I was writing some code yesterday which utilized throwing funcs and I found
some inconveniences which I think could be improved in some future version
of Swift.

1. *Default error handling*
Swift, unlike most languages, requires us to put try, try? or try! before
calling throwing funcs. When using try, we already have our do..catch block
surrounding the throwing func. Sometimes there are multiple cases where the
error is handled the same way, and there's a need to write the same
do..catch blocks every time, or just intercept the error in the throwing
func or a wrapping function for a throwing one, but then there is no
possibility to do the handling anymore if we want to handle it another way
in some specific case. I thought that this would be a good idea to
introduce something like default error handling e.g. with calling the func
without using the try keyword or do..catch block. In this case, a keyword
like throws? could be introduced to be used to use instead of throws when
defining a function. Such a function would:
1. Contain do..catch blocks, like normal throwing func
2. Would execute these do..catch blocks if the caller does not use a
variant of try when calling the func
3. Would not execute these do..catch blocks and pass the error to the
caller, the same way as the func would do if there would be no do..catch
blocks and the function was marked with "throws". In this case, the caller
would be the one to handle the error.

e.g.

enum SomeError: Error {
  case myError
}

func justThrowing() throws {
  throw SomeError.myError
}

func myFailableFunc() throws? {
  do {
    try justThrowing()
  } catch {
    print("Handled an error")
  }
}

func testing() {

  // This one would print "Handled an error"
  myFailableFunc()

  // This one would handle the error like any other func marked with
"throws"
  // try? and try! would also work exactly like for a normal throwing func
  do {
    try myFailableFunc()
  } catch {
    print("Handled this in the caller")
  }

}

2. *Grouping throwing function calls*

I think there are cases when people are not too concerned about an error
from multiple function calls in a row and what they want is to know if
these functions failed or not. This could be, for example, when these
operations are just doing some micro-work by calling the same func on
different instances of a type and are a part of some larger operation, it
is inconvenient to write try, try? or try! before each of them.

Instead, I would suggest introducing do try { ... } catch blocks or simply
allowing to use try like this:
try {
  throwingFunc1()
  throwingFunc2()
  throwingFunc3()
}

Now, we're forced to do it like this:
try throwingFunc1()
try throwingFunc2()
try throwingFunc3()

This often becomes inconvenient and looks messy in the code. I also think
that this concept could also work for try? and try!.


What are your opinions on these? Did you have any places in your code where
this could be useful?
If you have some better ideas on the concept or implementation, or have
some counterarguments to these suggestions, feel free to comment.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170302/f4796b41/attachment.html>


More information about the swift-evolution mailing list