Error Handling
Throw and catch typed errors with do-catch, try?, try!, and rethrows.
Code
import Foundation
// Error enum
enum APIError: Error, LocalizedError {
case badURL
case unauthorized
case status(Int)
var errorDescription: String? {
switch self {
case .badURL: "The URL was invalid"
case .unauthorized: "Authentication required"
case .status(let code): "Server returned \(code)"
}
}
}
// Throwing function
func fetch(_ url: String) throws -> String {
guard url.hasPrefix("https://") else { throw APIError.badURL }
if url.contains("login") { throw APIError.unauthorized }
return "data"
}
// do-catch
do {
let result = try fetch("https://api.example.com/data")
print(result)
} catch let err as APIError {
print("api error: \(err.localizedDescription)")
} catch {
print("other: \(error)")
}
// try? converts to optional
let opt: String? = try? fetch("ftp://x")
print(opt ?? "nil")
// try! crashes on error (use only when you're sure)
let ok = try! fetch("https://example.com")
print(ok)
// rethrows propagates caller errors
func process(_ block: () throws -> Int) rethrows -> Int { try block() * 2 }Explanation
Swift errors are values of types conforming to Error, thrown with throw and caught with do-catch. try? converts a thrown error into nil, while try! asserts it cannot happen. A function marked rethrows only throws when its closure parameter does, which keeps higher-order helpers composable.
More Swift Snippets
Optionals
Use optional binding, nil-coalescing, chaining, and guard for safe unwrapping.
Closures
Define closure expressions, capture state, and pass escaping callbacks.
Protocols
Define contracts, conform with structs, and add default behavior via extensions.
Generics
Write type-parameterized functions and types with protocol constraints.
Structs and Classes
Compare value-type structs with reference-type classes and inheritance.
Concurrency (async/await)
Run async functions, parallelize with async let, and fan out with task groups.