I have this error:
public enum AuthenticationError: Error { case unknownError case canceledByUser case userOrPasswordMismatch case unableToExtractOneTimeCode case unableToExchangeOneTimeCodeForToken case credentialsUnavailable case expired case webRequestFailed(error: Error) }
I'd like to overload ==
to compare it but I find I need to repeat the code three ways:
public func == (lhs: Error, rhs: AuthenticationError) -> Bool { return lhs._code == rhs._code && lhs._domain == rhs._domain } public func == (lhs: AuthenticationError, rhs: Error) -> Bool public func == (lhs: AuthenticationError, rhs: AuthenticationError) -> Bool
An usage example is:
if let error = error, error == AuthenticationError.expired { // do something }
Is there a better way to do this (with generics) so I don't need to repeat similar code?
This is by using the === operator. The === operator checks if two reference type variables point to the same object in memory. Now you understand how the === operator works in Swift classes and why it is important.
do – This keyword starts the block of code that contains the method that can potentially throw an error. try – You must use this keyword in front of the method that throws. Think of it like this: “You're trying to execute the method.
Similar to try? , try! doesn't need to be put inside do/catch block as well. The difference is that when an error is thrown, your app will crash instead of returning nil. This is similar to unwrapping a nil value in optionals.
This suffices for your .expired
check, without needing to define ==
:
let error: Error = ... if case AuthenticationError.expired = error { print("it's expired") }
If you want to extract associated data (as in the .webRequestFailed
case), you can do this:
if case AuthenticationError.webRequestFailed(error: let innerError) = error { print("web request failed due to \(innerError.localizedDescription)") }
Here's my macOS playground, created in Xcode 9.2:
import Foundation public enum AuthenticationError: Error { case unknownError case canceledByUser case userOrPasswordMismatch case unableToExtractOneTimeCode case unableToExchangeOneTimeCodeForToken case credentialsUnavailable case expired case webRequestFailed(error: Error) } func test(_ error: Error) { if case AuthenticationError.expired = error { print("it's expired; error = \(error)") } else if case AuthenticationError.webRequestFailed(error: let innerError) = error { print("web request failed due to \(innerError.localizedDescription); error = \(error)") } else { print("no match; error = \(error)") } } test(AuthenticationError.expired) test(AuthenticationError.webRequestFailed(error: AuthenticationError.credentialsUnavailable)) test(NSError(domain: NSPOSIXErrorDomain, code: Int(ENOENT), userInfo: [:]))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With