How to override localizedDescription for custom Error in Swift 3? [duplicate]
The documentation about new Error bridging feature is not clear enough still now, so this answer may need some updates in the near future, but according to SE-0112 and the latest Swift source code, you may need to use LocalizedError
rather than Error
and implement errorDescription
.
class MyError: NSObject, LocalizedError { var desc = "" init(str: String) { desc = str } override var description: String { get { return "MyError: \(desc)" } } //You need to implement `errorDescription`, not `localizedDescription`. var errorDescription: String? { get { return self.description } }}func test_my_code() { let error = MyError(str: "my test string") let x = error as Error print(x.localizedDescription)}test_my_code() //->MyError: my test string
Other than using LocalizedError
, this default implementation works:
(NSError.swift, the link shown above)
public extension Error { /// Retrieve the localized description for this error. var localizedDescription: String { return NSError(domain: _domain, code: _code, userInfo: nil).localizedDescription }}
It is a little complicated how Swift defines _domain
or _code
from arbitrary types just conforming to Error
, but it seems that NSError
generates "The operation couldn’t be completed..." for unknown combinations of domain and code.
If custom type conforms to protocol CustomStringConvertible
and provides localized description
, then the following extension of LocalizedError
might be useful:
extension LocalizedError where Self: CustomStringConvertible { var errorDescription: String? { return description }}
Example code:
class MyError: LocalizedError, CustomStringConvertible { let desc: String init(str: String) { desc = str } var description: String { let format = NSLocalizedString("Operation error: %@", comment: "Error description") return String.localizedStringWithFormat(format, desc) }}let error = MyError(str: "my test string")let x = error as Errorprint(x.localizedDescription) // Prints "Operation error: my test string"print(String(describing: x)) // Prints "Operation error: my test string"