throws / try / do-catch
Swift error handling follows a pattern of declaring errors with throws, calling with try, and catching with do-catch.
Syntax
// Define a throwing function
func functionName() throws -> Type {
// Throw an error
throw error
}
// Standard call (do-catch)
do {
let result = try functionName()
} catch ErrorType.case {
// Handle a specific error
} catch {
// Handle any other error (the error variable is available)
}
// Convert to Optional (nil on failure)
let result = try? functionName()
// Force-try (crashes on failure)
let result2 = try! functionName()
Syntax Overview
| Syntax | Description |
|---|---|
| throws | Declares that a function can throw an error. |
| throw error | Throws an error and immediately exits the function. |
| try expression | Calls a throwing function. Must be used inside a do-catch block. |
| try? expression | Returns nil if an error is thrown (converts the result to an Optional). |
| try! expression | Use when you are certain no error will be thrown. Crashes if an error occurs. |
| rethrows | Propagates an error only if a closure passed as an argument throws one. |
Sample Code
enum ParseError: Error {
case invalidFormat
case outOfRange(value: Int)
}
// Define a throwing function
func parseAge(_ input: String) throws -> Int {
guard let age = Int(input) else {
throw ParseError.invalidFormat
}
guard (0...150).contains(age) else {
throw ParseError.outOfRange(value: age)
}
return age
}
// Handle errors with do-catch
func processInput(_ input: String) {
do {
let age = try parseAge(input)
print("Age: \(age)")
} catch ParseError.invalidFormat {
print("Error: Please enter a number.")
} catch ParseError.outOfRange(let value) {
print("Error: \(value) is out of range (0–150).")
} catch {
print("Unexpected error: \(error)")
}
}
processInput("25")
processInput("abc")
processInput("200")
// try?: Convert to Optional
let age1 = try? parseAge("30") // Optional(30)
let age2 = try? parseAge("invalid") // nil
print("age1: \(age1 as Any)")
print("age2: \(age2 as Any)")
// rethrows: Propagate errors from a closure
func apply(_ value: Int, _ transform: (Int) throws -> Int) rethrows -> Int {
return try transform(value)
}
let result = try? apply(10) { v in
if v < 0 { throw ParseError.outOfRange(value: v) }
return v * 2
}
print("result: \(result as Any)")
Notes
Swift error handling is type-safe. Any function marked with throws must be called with try, and the compiler will flag missing error handling.
Catch clauses are evaluated from top to bottom. Write more specific error cases first and leave the general catch for last. Use try! only when you are absolutely certain no error will occur. If an error is thrown, the app will crash.
For error handling with the Result type, see Result<Success, Failure>.
If you find any errors or copyright issues, please contact us.