Typed throws in Swift

Nov 07, 2024#swift

Typed throws have been in high demand ever since Swift gained the throws keyword. The error values themselves are always type-erased to any Error. This approach encourages errors to be handled generically, and remains a good default for most code.

Finally this feature was introduced in proposal SE-0413 and implemented in Swift 6.0

Typed throws provides several benefits:

  • Where you need to handle errors exhaustively
  • Propagate errors from arguments but never generate errors itself
  • Avoid the overhead associated with existential types like any Error

Errors are usually propagated or rendered, but not exhaustively handled, so even with the addition of typed throws to Swift, untyped throws is better for most scenarios.

  1. Using throws with a specific error type
enum AppError: Error {
    case invalid
    case network
}

func foo() throws(AppError) {
    // ...
}
  1. Using throws with any Error is equivalent to untyped throws
func foo() throws(any Error) { ... }
func foo() throws { ... }
  1. Using throws with Never is equivalent to a non-throwing
func foo() throws(Never) { ... }
func foo() { }