Different custom errors & system errors conform to a custom protocol, in this example LoggableError
.
However, when trying to check the conformance of that Error
to that custom protocol, Swift fails to cast or even check it (with an is
-check).
My class receives an Error, but cannot check if the error implements the custom protocol or not.
Example:
import Foundation
protocol LoggableError: Error {
var message: String { get }
}
extension URLError: LoggableError {
var message: String {
switch code {
case .notConnectedToInternet: return "no internet"
default: return ""
}
}
}
func log(error: Error) {
guard let error = error as? LoggableError else { // This cast fails
return
}
print(error.message)
}
let error = URLError(.notConnectedToInternet)
log(error: error)
Note that when casting to URLError in that log(error:)
method, the conformance is checkable & error is cast-able. 🤯
Any ideas here?
The problem you are seeing is caused by the fact that protocol's don't conform to themselves.
By changing your log
method to take its error
type as a generic parameter rather than an Error
existential, you can solve the problem, since the generic type now conforms to LoggableError
, unlike the existential Error
.
func log<E: Error>(error: E) {
guard let error = error as? LoggableError else {
return
}
print(error.message)
}
Or you can use some Error
as a shorthand instead of having to declare the method generic.
func log(error: some Error) {