I'm looking for a way to catch multiple types of errors in a catch
. I've tried fallthrough
and the comma separated style from a switch statement and neither works. The docs say nothing about catching multiple but pattern 1
. It's not clear to me which of the pattern syntaxes would work here.
Error definitions (sample):
enum AppErrors {
case NotFound(objectType: String, id: Int)
case AlreadyUsed
}
Works:
do {
//...
} catch AppErrors.NotFound {
makeNewOne()
} catch AppErrors.AlreadyUsed {
makeNewOne()
} catch {
print("Unhandled error: \(error)")
}
Does not compile, is it possible to do something like this?
do {
//...
} catch AppErrors.NotFound, AppErrors.AlreadyUsed {
makeNewOne()
} catch {
print("Unhandled error: \(error)")
}
If you want to catch all AppErrors
, you can use this pattern:
catch is AppErrors
If you're looking for more specific matching, it seems to quickly get ugly.
This will let us catch specific cases of AppErrors
:
catch let error as AppErrors where error == .NotFound || error == .AlreadyUsed
There's also this syntax which seems to work:
catch let error as AppErrors where [.NotFound, .AlreadyUsed].contains(error)
For completeness sake, I'll also add this option, which allows us to catch errors of two different types, but it doesn't allow us to specify which case within those types:
catch let error where error is AppErrors || error is NSError
Finally, based on the fact that anything we catch will conform to the ErrorType
protocol, we can clean up the second & third examples I provided with an ErrorType
extension and use that in conjunction where a where
clause in our catch
:
extension ErrorType {
var isFooError: Bool {
guard let err = self as? AppErrors else { return false }
return err == .NotFound || err == .AlreadyUsed
}
}
And just catch it like this:
catch let error where error.isFooError
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