Lesson 6 of 8

Errors & async/await

Learn how to throw and handle and how to call asynchronous code with /await. Swift marks both in the code: throws in a signature and await at the call site.

Swift
enum FileError: Error {
    case notFound(path: String)
    case noPermission
}

func read(file path: String) throws -> String {
    guard path.hasSuffix(".txt") else {
        throw FileError.notFound(path: path)
    }
    return "file contents"
}

// Callers must acknowledge the risk with 'try':
do {
    let text = try read(file: "notes.txt")
    print(text)
} catch FileError.notFound(let path) {
    print("missing: \(path)")
} catch {
    print("other error: \(error)")
}

let maybe = try? read(file: "bad.pdf")   // nil on failure
Swift
// async/await — modern Swift concurrency:
struct User: Codable {
    let login: String
    let name: String?
}

func fetchUser(_ username: String) async throws -> User {
    let url = URL(string: "https://api.github.com/users/\(username)")!
    let (data, _) = try await URLSession.shared.data(from: url)
    return try JSONDecoder().decode(User.self, from: data)
}

// Run concurrently with async let:
func fetchTwo() async throws {
    async let a = fetchUser("octocat")
    async let b = fetchUser("torvalds")
    let (first, second) = try await (a, b)
    print(first.login, second.login)
}
Finished reading?Mark it done to track your progress.

Tip: use the ← and → keys to move between lessons.