I am defining a custom error type with Swift 3 syntax and I want to provide a user-friendly description of the error which is returned by the localizedDescription
property of the Error
object. How can I do it?
public enum MyError: Error { case customError var localizedDescription: String { switch self { case .customError: return NSLocalizedString("A user-friendly description of the error.", comment: "My error") } } } let error: Error = MyError.customError error.localizedDescription // "The operation couldn’t be completed. (MyError error 0.)"
Is there a way for the localizedDescription
to return my custom error description ("A user-friendly description of the error.")? Note that the error object here is of type Error
and not MyError
. I can, of course, cast the object to MyError
(error as? MyError)?.localizedDescription
but is there a way to make it work without casting to my error type?
As described in the Xcode 8 beta 6 release notes,
Swift-defined error types can provide localized error descriptions by adopting the new LocalizedError protocol.
In your case:
public enum MyError: Error { case customError } extension MyError: LocalizedError { public var errorDescription: String? { switch self { case .customError: return NSLocalizedString("A user-friendly description of the error.", comment: "My error") } } } let error: Error = MyError.customError print(error.localizedDescription) // A user-friendly description of the error.
You can provide even more information if the error is converted to NSError
(which is always possible):
extension MyError : LocalizedError { public var errorDescription: String? { switch self { case .customError: return NSLocalizedString("I failed.", comment: "") } } public var failureReason: String? { switch self { case .customError: return NSLocalizedString("I don't know why.", comment: "") } } public var recoverySuggestion: String? { switch self { case .customError: return NSLocalizedString("Switch it off and on again.", comment: "") } } } let error = MyError.customError as NSError print(error.localizedDescription) // I failed. print(error.localizedFailureReason) // Optional("I don\'t know why.") print(error.localizedRecoverySuggestion) // Optional("Switch it off and on again.")
By adopting the CustomNSError
protocol the error can provide a userInfo
dictionary (and also a domain
and code
). Example:
extension MyError: CustomNSError { public static var errorDomain: String { return "myDomain" } public var errorCode: Int { switch self { case .customError: return 999 } } public var errorUserInfo: [String : Any] { switch