Contributors: 5 Tuesday, August 2, 2016
Licensed under: CC-BY-SA
Not affiliated with Stack Overflow
Rip Tutorial:
Roadmap: roadmap

Error handling basics

Download swift eBook


Functions in Swift may return values, throw errors, or both:

func reticulateSplines()                // no return value and no error
func reticulateSplines() -> Int         // always returns a value
func reticulateSplines() throws         // no return value, but may throw an error
func reticulateSplines() throws -> Int  // may either return a value or throw an error

Any value which conforms to the ErrorType protocol (including NSError objects) can be thrown as an error. Enumerations provide a convenient way to define custom errors:

enum NetworkError: ErrorType {
    case Offline
    case ServerError(String)
enum NetworkError: Error {
    // Swift 3 dictates that enum cases should be `lowerCamelCase`
    case offline
    case serverError(String)

An error indicates a non-fatal failure during program execution, and is handled with the specialized control-flow constructs do/catch, throw, and try.

func fetchResource(resource: NSURL) throws -> String {
    if let (statusCode, responseString) = /* ...from elsewhere...*/ {
        if case 500..<600 = statusCode {
            throw NetworkError.serverError(responseString)
        } else {
            return responseString
    } else {
        throw NetworkError.offline

Errors can be caught with do/catch:

do {
    let response = try fetchResource(resURL)
    // If fetchResource() didn't throw an error, execution continues here:
    print("Got response: \(response)")
} catch {
    // If an error is thrown, we can handle it here.
    print("Whoops, couldn't fetch resource: \(error)")

Any function which can throw an error must be called using try, try?, or try!:

// error: call can throw but is not marked with 'try'
let response = fetchResource(resURL)

// "try" works within do/catch, or within another throwing function:
do {
    let response = try fetchResource(resURL)
} catch {
    // Handle the error

func foo() throws {
    // If an error is thrown, continue passing it up to the caller.
    let response = try fetchResource(resURL)

// "try?" wraps the function's return value in an Optional (nil if an error was thrown).
if let response = try? fetchResource(resURL) {
    // no error was thrown

// "try!" crashes the program at runtime if an error occurs.
let response = try! fetchResource(resURL)