Member-only story
Avoiding Nested Try/Catch Blocks
A common pattern in Swift that’s easy to avoid.
4 min read 3 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 {…