Swift

Module 10: Swift Error Handling Tutorial – Learn do-try-catch & Throwing Functions

Module 10: Error Handling in Swift – do-try-catch, Throwing Functions & More

Error handling is a crucial part of writing robust and safe software. In Swift, error handling enables you to anticipate, catch, and respond to runtime errors gracefully, instead of your program crashing unexpectedly. Swift uses a clean and expressive syntax based on do-try-catch blocks to handle errors. This module will guide you through the essentials of Swift error handling, including throwing errors, handling them with do-try-catch, and the optional error handling shortcuts like try? and try!.

What is Error Handling?

In Swift, errors are values of types that conform to the Error protocol. Functions or methods can throw errors when something unexpected happens, such as a file not being found or invalid user input. Instead of returning a failure code, Swift uses throwing functions to propagate errors up the call stack.

Defining and Throwing Errors

To start, you create an enum that conforms to the Error protocol. Each case in the enum represents a specific error.

Example:
enum FileError: Error {
case fileNotFound
case unreadable
case encodingFailed
}

Then, a function that can throw errors is marked with the throws keyword:

Example:
func readFile(named fileName: String) throws -> String {
guard fileName == “file.txt” else {
throw FileError.fileNotFound
}
// Simulate file content reading
return “File content here”
}

Using do-try-catch Blocks

When you call a throwing function, you use the try keyword. To handle possible errors, you wrap the call in a do block with catch clauses:

Example:
do {
let content = try readFile(named: “data.txt”)
print(content)
} catch FileError.fileNotFound {
print(“Error: The file was not found.”)
} catch {
print(“An unexpected error occurred: \(error)”)
}

– If readFile throws an error, execution jumps to the matching catch block.
– If no error occurs, the file content is printed normally.

Using try? and try!

Swift provides shorthand ways to handle errors when you want to ignore them or are sure they won’t occur:

  • try? converts the result into an optional. If an error occurs, the result is nil.

Example:
let content = try? readFile(named: “file.txt”)
print(content ?? “No content”)

  • try! forces the call and crashes if an error is thrown. Use it only when you’re certain no error will occur.

Example:
let content = try! readFile(named: “file.txt”)
print(content)

Throwing Functions with Multiple Error Types

You can define multiple error cases and catch them individually for granular error handling:

Example:
enum NetworkError: Error {
case disconnected
case timeout
case badResponse
}

func fetchData() throws {
throw NetworkError.timeout
}

do {
try fetchData()
} catch NetworkError.timeout {
print(“Request timed out, please try again.”)
} catch NetworkError.disconnected {
print(“No internet connection.”)
} catch {
print(“Unknown network error”)
}

Rethrowing Functions

Sometimes you write functions that call throwing functions but don’t throw errors themselves. You can declare them as rethrows to propagate the error only if the called function throws:

Example:
func perform(operation: () throws -> Void) rethrows {
try operation()
}

do {
try perform {
throw FileError.unreadable
}
} catch {
print(“Caught error from operation: \(error)”)
}

Summary

  • Swift’s error handling uses the Error protocol, throws keyword, and do-try-catch blocks.
  • You define errors with enums conforming to Error.
  • Use try? and try! for simplified error handling when appropriate.
  • Catch specific errors for fine-grained control.
  • Use rethrows for functions that propagate errors from function parameters.

Error handling is essential for writing safe, predictable Swift code, especially when working with file I/O, networking, or user input validation.

Leave a Reply

Your email address will not be published. Required fields are marked *