Skip to content
Swift

Error Handling

Throw and catch typed errors with do-catch, try?, try!, and rethrows.

By EZ4Code Team
errorthrows

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