Error Handling and HTTP Status Codes
Checking response status codes and mapping errors into typed domain errors.
Error Handling and HTTP Status Codes is a free Swift Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Swift Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
HTTP Status Ranges
HTTP responses signal success or failure via status codes: 2xx success, 3xx redirect, 4xx client error, 5xx server error.
// 200 OK, 201 Created
// 400 Bad Request, 401 Unauthorized, 404 Not Found
// 500 Internal Server ErrorChecking Status in Swift
Cast URLResponse to HTTPURLResponse and check statusCode after an async request.
let (data, response) = try await URLSession.shared.data(from: url)
guard let http = response as? HTTPURLResponse else {
throw NetworkError.invalidResponse
}
guard (200..<300).contains(http.statusCode) else {
throw NetworkError.httpError(http.statusCode)
}Typed Network Errors
Define a typed error enum for network failures to enable exhaustive catch blocks.
enum NetworkError: Error {
case invalidURL
case invalidResponse
case httpError(Int)
case decodingError(Error)
case noData
}Mapping Status Codes to Errors
Switch on status codes to emit meaningful domain errors instead of raw integers.
switch http.statusCode {
case 200..<300: break // success
case 401: throw NetworkError.unauthorized
case 404: throw NetworkError.notFound
case 500..<600: throw NetworkError.serverError(http.statusCode)
default: throw NetworkError.httpError(http.statusCode)
}Decoding Error Responses
When the status is an error, the body often contains a JSON error message. Decode it for better diagnostics.
if http.statusCode != 200 {
struct APIError: Decodable { var message: String }
let apiError = try? JSONDecoder().decode(APIError.self, from: data)
throw NetworkError.serverMessage(apiError?.message ?? "Unknown error")
}Propagating Errors in async
Swift's structured concurrency propagates errors naturally: a thrown error cancels sibling tasks in a TaskGroup.
async let users = fetchUsers()
async let posts = fetchPosts()
let (u, p) = try await (users, posts) // if either throws, both cancelCatching Specific Errors
Use typed catch blocks to handle different error kinds distinctly in calling code.
do {
let items = try await fetchItems()
} catch NetworkError.unauthorized {
showLoginScreen()
} catch NetworkError.httpError(let code) {
print("HTTP Error: \(code)")
} catch {
print("Unexpected: \(error)")
}URLError Codes
URLError describes connectivity failures: .notConnectedToInternet, .timedOut, .cannotFindHost.
do {
let (data, _) = try await URLSession.shared.data(from: url)
} catch let urlError as URLError where urlError.code == .notConnectedToInternet {
print("No internet connection")
}Result Wrapper for Networking
Return Result from fetch functions when you want callers to handle errors without try/catch.
func fetchUser() async -> Result<User, NetworkError> {
do {
let user = try await performFetch()
return .success(user)
} catch let e as NetworkError {
return .failure(e)
} catch {
return .failure(.unknown)
}
}Error Logging
Log network errors with relevant context (URL, status code, body) to aid debugging in production.
func log(_ error: NetworkError, url: URL) {
print("[Network] \(url.absoluteString) → \(error)")
}User-Facing Error Messages
Map technical errors to user-friendly strings. Never show raw HTTP status codes in the UI.
extension NetworkError: LocalizedError {
var errorDescription: String? {
switch self {
case .unauthorized: return "Please log in again."
case .notFound: return "The requested item was not found."
case .serverError: return "Server error. Please try again later."
default: return "Something went wrong."
}
}
}Quick Check
Which HTTP status code range indicates a successful response?
Lesson Recap
After URLSession.data(from:), cast to HTTPURLResponse and check statusCode. Map codes to typed Error cases. Use URLError for connectivity failures. Propagate errors with try/throw and catch them with typed catch blocks.
Frequently asked questions
Is the “Error Handling and HTTP Status Codes” lesson free?
Yes — the full text of “Error Handling and HTTP Status Codes” is free to read here on the web, and the Swift Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Swift Academy course, upgrade to CoddyKit PRO.
What will I learn in “Error Handling and HTTP Status Codes”?
Checking response status codes and mapping errors into typed domain errors. You practise Swift Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Swift Academy?
No prior experience is required. Swift Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Error Handling and HTTP Status Codes” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Swift Academy lesson?
Yes. Every Swift Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- URLSession data(from:) with async/await
- Codable: Encoding and Decoding JSON
- Error Handling and HTTP Status Codes
- Retry Logic and Background URLSession