Errors and recovery
Decide what a caller should do when work fails.
Name a failure
A type that conforms to Error can describe failures precisely. A small enum is useful for a finite set of domain errors. throws makes the possibility of failure explicit to callers.
Handle errors at a boundary
try marks a throwing operation. do/catch lets the caller recover, add context, or present an error. Catch specific cases when behavior should differ, and preserve diagnostic information for unexpected errors.
Choose the right representation
An optional is useful for ordinary absence. A Result value can carry success or failure as stored data. A thrown error works well when failure should propagate through a sequence of operations.
Try it yourself
enum InputError: Error { case negative }
func square(_ value: Int) throws -> Int {
guard value >= 0 else { throw InputError.negative }
return value * value
}
do { print(try square(-2)) }
catch InputError.negative { print("Use a nonnegative number") }
catch { print(error) }This example assumes small integers. Large multiplication can overflow.