← Back to Swift Course | Chapter 11: Error Handling | Lesson 2 of 6

throw, try, and catch

throw is raising your hand to say something went wrong, try is attempting something that might fail, and catch is what handles it if it does.
Syntax
swift
func functionName() throws -> ReturnType {
    throw ErrorName.caseName
}

do {
    let result = try functionName()
} catch ErrorName.caseName {
    // handle specific error
} catch {
    // handle any other error
}

Declaring and Throwing an Error

A function marked throws can use throw to raise an error instead of returning normally when something goes wrong.

Example: Declaring and Throwing an Error

markup
// Define an enum `ValidationError` listing its possible cases
enum ValidationError: Error {
    // Case `empty`
    case empty
}
func validate(_ text: String) throws -> String {
    // Check whether `text.isEmpty`
    if text.isEmpty {
        throw ValidationError.empty
    }
    // Return `text` from this function
    return text
}
do {
    // Declare a constant `result`, set to `try validate("Hello")`
    let result = try validate("Hello")
    // Print "Valid: \(result)" to the console
    print("Valid: \(result)")
} catch {
    // Print "Validation failed: \(error)" to the console
    print("Validation failed: \(error)")
}

Handling Multiple Error Cases

Multiple catch clauses can match specific error cases in order, similar to a switch statement, with a final unmatched catch as a fallback.

Example: Handling Multiple Error Cases

markup
// Define an enum `ValidationError` listing its possible cases
enum ValidationError: Error {
    // Case `empty`
    case empty
    // Case `tooShort`
    case tooShort
}
func validate(_ text: String) throws -> String {
    // Check whether `text.isEmpty { throw ValidationError.empty }`
    if text.isEmpty { throw ValidationError.empty }
    // Check whether `text.count < 3 { throw ValidationError.tooShort }`
    if text.count < 3 { throw ValidationError.tooShort }
    // Return `text` from this function
    return text
}
do {
    // Declare a constant `result`, set to `try validate("hi")`
    let result = try validate("hi")
    // Print "Valid: \(result)" to the console
    print("Valid: \(result)")
} catch ValidationError.empty {
    // Print "Text was empty" to the console
    print("Text was empty")
} catch ValidationError.tooShort {
    // Print "Text was too short" to the console
    print("Text was too short")
} catch {
    print("Unknown error")
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Forgetting to mark a function that can throw with throws in its signature -- Swift won't let you throw from a non-throwing function.
  2. Calling a throwing function without try in front of it; every call to a throwing function must be prefixed with try, try?, or try!.
  3. Writing a catch block that doesn't match any specific error case; a plain catch at the end acts as a catch-all, but a mismatched typed catch just falls through.
Chapter Summary
  • A function that can fail is marked with throws after its parameter list.
  • throw someError raises an error, stopping normal execution of the current function.
  • Calling a throwing function requires try, and the call is usually wrapped in do { } catch { }.
  • Multiple catch blocks can match specific error cases, similar to a switch.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.