Every file, network and decoding API in Swift throws, and you must handle errors explicitly to call it.
Errors are values conforming to the Error protocol — typically an enum: enum ParseError: Error { case empty, badNumber(String) }.
A function that can fail is marked throws. It uses throw to fail, and every call to it must be marked with try, so failure points are visible in the source.
Handle errors with do/catch:
do {
let n = try parse(text)
} catch ParseError.badNumber(let s) {
print("bad:", s)
} catch {
print(error) // implicit `error` binding
}Alternatives to do/catch:
try?converts the result to an optional, discarding the error.try!crashes on error — only for failures that are programmer mistakes.- Propagate by marking your own function
throwsand just writingtry.
Swift 6 adds typed throws: func parse(_ s: String) throws(ParseError) -> Int. Callers then know the exact error type, and catch binds error as ParseError. Plain throws means throws(any Error). Typed throws suit low-level code and closed error sets; most app code keeps untyped throws.
Result<Success, Failure> stores an outcome as a value, which helps when passing results around; try result.get() turns it back into a throw.
Use defer { } to run cleanup when the scope exits, whether normally or by throwing.
Example
enum ParseError: Error {
case empty
case badNumber(String)
}
func parse(_ text: String) throws(ParseError) -> Int {
guard !text.isEmpty else { throw .empty }
guard let n = Int(text) else { throw .badNumber(text) }
return n
}
for input in ["42", "", "x1"] {
do {
defer { print("checked \"\(input)\"") }
print(try parse(input) * 2)
} catch ParseError.badNumber(let s) {
print("not a number:", s)
} catch {
print("other error:", error)
}
}
// 84 / checked "42" / checked "" / other error: empty / ...
print(String(describing: try? parse("7"))) // Optional(7)Remember
- Mark failing functions
throwsand every calltry try?turns errors into nil;try!crashes- Typed throws
throws(E)gives callers a concrete error type
Watch out for
- Using
try?everywhere and silently losing the reason something failed.