Member-only story

Avoiding Nested Try/Catch Blocks

A common pattern in Swift that’s easy to avoid.

Michael Long
4 min read3 days ago

This is a quick one, and a departure from the Navigator series, but I’ve seen this anti-pattern a lot and just thought I’d mention how easy it is to avoid.

When making API calls, it’s a fairly common practice to want to map any errors that might occur into a more finite set of “known” errors that are easier to handle.

An example might be:

public enum NetworkError: Error {
case data
case server
case status(Int)
case validation(String)
}

Note the “data” error we want to display in case our data is corrupted or in an unknown format.

Nested Try/Catch

With that in mind, take a peek at the following code.

public func load1(url: URL) async throws -> [FeedItem] {
do {
let (data, response) = try await URLSession.shared.data(from: url)

guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
throw NetworkError.status((response as? HTTPURLResponse)?.statusCode ?? 500)
}

do {
let decoder = JSONDecoder()
let items = try decoder.decode([FeedItem].self, from: data)
return items
} catch {…

--

--

Michael Long
Michael Long

Written by Michael Long

I write about Apple, Swift, and SwiftUI in particular, and technology in general. I'm also a Lead iOS Engineer at InRhythm, a modern digital consulting firm.

Responses (2)