- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
How to provide a localized description with an Error type in Swift?
Swift provides a protocol to achieve the localized description. You can use the LocalizedError protocol to provide a localized description of an error type. This protocol can be conformed by structure, enum, or class. After adopting this protocol, you have to implement the errorDescription property to provide the localized description.
Here is an example of a custom error enum that conforms to the LocalizedError protocol −
Create a custom error and conform to the Error type
In this example, we will create an enum called CustomError to conform to the LocalizedError protocol. In the enum, we will add cases to define the different types of errors. Each error will represent a different error. Here is the example of creating an enum with an Error type −
Example
import Foundation // An enum with different error types. enum CustomError: Error { case invalidUrl case httpError case timeoutError case noConnectionError case encodingError case decodingError case invalidResponseError case unexpected(code: Int) }
In the above code, we created an enum called CustomError with Error type. The same enum we will use to conform to the different protocols to localize the description.
Conforms to the CustomStringConvertible Protocol
First, we will see an example with the CustomStringConvertible protocol. Using this, you can provide a custom message for each type of error. To provide a custom message, you can override the description property.
Example
Here is an example to extend the CustomError enum by conforming to the CustomStringConvertible protocol −
// Assign an appropriate description to each type of error. extension CustomError: CustomStringConvertible { var description: String { switch self { case .invalidUrl: return "There is a problem with a URL, such as an invalid URL or a timeout." case .httpError: return "There is an issue with an HTTP request or response." case .timeoutError: return "The request takes longer than the specified timeout period to complete." case .noConnectionError: return "There is no internet connection or the device is offline." case .encodingError: return "The data received from the server is unable to be encoded as the expected type." case .decodingError: return "The data received from the server is unable to be decoded as the expected type." case .invalidResponseError: return "The server responds with an unexpected format or status code." case .unexpected(let code): return "There is an unexpected error with the code \(code)" } } }
Add localizedDescription for custom errors using LocalizedError
In this step, you will see how to conform to the LocalizedError protocol to provide the localized descriptions for each error type. Once you conform to the LocalizedError protocol, you can override the errorDescription property to provide localization.
Example
Here is an example to extend the CustomError enum with LocalizedError protocol −
// Assign a localized description to each type of error. extension CustomError: LocalizedError { var errorDescription: String? { switch self { case .invalidUrl: return NSLocalizedString("There is a problem with a URL, such as an invalid URL or a timeout.", comment: "Invalid URL") case .httpError: return NSLocalizedString("There is an issue with an HTTP request or response.", comment: "HTTP Error") case .timeoutError: return NSLocalizedString("The request takes longer than the specified timeout period to complete.", comment: "Timeout Error") case .noConnectionError: return NSLocalizedString("There is no internet connection or the device is offline.", comment: "Internet Connection Error") case .encodingError: return NSLocalizedString("The data received from the server is unable to be encoded as the expected type.", comment: "Encoding Error") case .decodingError: return NSLocalizedString("The data received from the server is unable to be decoded as the expected type.", comment: "Decoding Error") case .invalidResponseError: return NSLocalizedString("The server responds with an unexpected format or status code.", comment: "Invalid Response Error") case .unexpected(let code): return NSLocalizedString("There is an unexpected error with the code \(code)", comment: "Unexpected Error") } } }
Extending Custom Error
In Swift, an enum has more power that provides you to extend its functionality. You can add computed properties and functions to an enum.
We will add a computed property to determine whether the error is the fatal type or not. In other words, we will check whether the error can be handled or not. For example −
// Checking for unexpected errors that cannot be handled. extension CustomError { var isFatal: Bool { if case CustomError.unexpected = self { return true } else { return false } } }
Practical Usage
We are ready with the custom errors with the localized description. Now, let’s see how to use them in your project.
Example
func checkServerResponse(_ response: [String: Any]?) -> CustomError? { // check for valid response guard let responseDictionary = response else { return CustomError.invalidResponseError } // check for valid status code guard let statusCode = responseDictionary["statusCode"] as? Int, statusCode >= 200 && statusCode <= 300 else { return CustomError.unexpected(code: -1002) } // check for valid data object guard let dataDictionary = responseDictionary["data"] as? [String: Any] else { return CustomError.encodingError } print("Received Data: \(dataDictionary)") return nil } let response: [String: Any] = ["statusCode": 201, "data": "user name"] if let error = checkServerResponse(response) { print("Error description: \(error.description)\nLocalized Description: \(error.localizedDescription)\nFatal Status: \(error.isFatal)") }
Output
Error description: The data received from the server is unable to be encoded as the expected type. Localized Description: The data received from the server is unable to be encoded as the expected type. Fatal Status: false
In the above example, we created a function to check the response received from the server. In case any error is found, this function returns a custom error type of optional type.
In the function implementation, we check for different valid cases. At each check, return a custom error if something is wrong.
Conclusion
In real applications, most of the time you deal with network requests. It is obvious you have to manage the different types of errors. In Swift, there some protocols which you can conforms and extends the capability to understand the error with custom messages or localized description.
The CustomStringConvertible protocol can be used to provide the custom message by overriding the description property. You can give meaningful message to each error types. The LocalizedError protocol can also be used to provide a localized description of an error type. It's good practice to use this feature to show a user-friendly message when an error occurs.