How to override localizedDescription for custom Error in Swift 3?
Solution 1
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.
Solution 2
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 Error
print(x.localizedDescription) // Prints "Operation error: my test string"
print(String(describing: x)) // Prints "Operation error: my test string"
![Maxim Kholyavkin](https://i.stack.imgur.com/GEsPb.jpg?s=256&g=1)
Maxim Kholyavkin
Want me to hire? I do not work with fixed price. Only hourly/part time/full time. I care about code quality and my rate begin from 40$ per hour. All my opensource code is available with two links: https://bitbucket.org/Speakus/ https://github.com/Speakus/ You could contact me via skype:speakus.net or same gmail user. Telegram: @Speakus
Updated on June 27, 2022Comments
-
Maxim Kholyavkin about 2 years
Error protocol has only one property localizedDescription. I tried to create custom object inherited from NSObject and Error but I can not override localizedDescription. How can I do that?
This code does not allow me to get custom description:
class MyError: NSObject, Error { var desc = "" init(str: String) { desc = str } override var description: String { get { return "MyError: \(desc)" } } var localizedDescription: String { get { return self.description } } } func test_my_code() { let error = MyError(str: "my test string") let x = error as Error print(x.localizedDescription) }
Calling function "test_my_code" get unexpected result: "The operation couldn’t be completed...".
What should I do to get result "MyError: my test string" ?