NetworkingMidOpen-ended
How do you handle API errors gracefully?
Explanation & Code
Answer: Define a clear error type, validate HTTP status codes, and propagate errors up to the UI where they can be shown to the user.
Code Example:
enum APIError: LocalizedError {
case badURL
case unauthorized
case notFound
case serverError(Int)
case decodingFailed(Error)
case unknown
var errorDescription: String? {
switch self {
case .unauthorized: return "Please log in again."
case .notFound: return "Resource not found."
case .serverError(let code): return "Server error (\(code))."
default: return "Something went wrong."
}
}
}
func fetch<T: Decodable>(_ type: T.Type, from url: URL) async throws -> T {
let (data, response) = try await URLSession.shared.data(from: url)
guard let http = response as? HTTPURLResponse else { throw APIError.unknown }
switch http.statusCode {
case 200...299: break
case 401: throw APIError.unauthorized
case 404: throw APIError.notFound
default: throw APIError.serverError(http.statusCode)
}
do {
return try JSONDecoder().decode(T.self, from: data)
} catch {
throw APIError.decodingFailed(error)
}
}
Rate your understanding: