Error / Defining Errors with enum
In Swift, you define custom errors using an enum that conforms to the Error protocol. By associating values with error cases, you can pass detailed error information to the caller.
Syntax
// Define a custom error
enum ErrorName: Error {
case case1
case case2(detail: String)
}
// LocalizedError: provides user-facing messages
enum ErrorName: LocalizedError {
case case1
var errorDescription: String? {
switch self {
case .case1: return "Description of the error"
}
}
}
Protocol Overview
| Protocol | Description |
|---|---|
| Error | The base protocol for error types. Enums commonly conform to this protocol. |
| LocalizedError | Extends Error to provide localized error messages. |
| errorDescription | A property of LocalizedError. Returns a description of the error. |
| failureReason | A property of LocalizedError. Returns the reason the error occurred. |
| recoverySuggestion | A property of LocalizedError. Returns a suggestion for recovering from the error. |
Sample Code
// Define a custom error
enum NetworkError: Error {
case notFound
case unauthorized
case serverError(statusCode: Int)
case timeout(after: Double)
}
// Add user-facing messages via LocalizedError
extension NetworkError: LocalizedError {
var errorDescription: String? {
switch self {
case .notFound:
return "Page not found (404)"
case .unauthorized:
return "Authentication required (401)"
case .serverError(let code):
return "A server error occurred (\(code))"
case .timeout(let seconds):
return "Request timed out after \(seconds) seconds"
}
}
}
// Use the error
func fetchData(url: String) throws -> String {
guard url.starts(with: "https") else {
throw NetworkError.unauthorized
}
guard url != "https://example.com/missing" else {
throw NetworkError.notFound
}
return "Data fetched successfully"
}
// Handle errors with do-catch
do {
let data = try fetchData(url: "https://example.com/missing")
print(data)
} catch let error as NetworkError {
print("Network error: \(error.localizedDescription)")
} catch {
print("Other error: \(error)")
}
// Convert to Optional using try?
let result = try? fetchData(url: "https://example.com/api")
print("Result: \(result ?? "Failed")")
Notes
Swift error handling uses throws, try, and do-catch together. Errors can be defined as any type conforming to the Error protocol, but enums are the most common choice.
Conforming to LocalizedError lets you retrieve user-facing messages via error.localizedDescription. Swift error handling is not exception-based — it is "error propagation." When an error is thrown, the function exits immediately and the caller is responsible for handling it.
For more on throws / try / do-catch, see throws / try / do-catch.
If you find any errors or copyright issues, please contact us.