Using Swift 4.2 and XCode 10
In Swift 4.2, DecodingError is an enumeration. There are (currently) four different cases. I can catch each case separately, and bind variables that I can use to log the error as in the following code ...
do {
let model = try jsonDecoder.decode(BattleShip.self, from: jsonData!)
print(model)
} catch DecodingError.dataCorrupted(let context) {
print(context.debugDescription)
} catch DecodingError.keyNotFound(let key, let context) {
print("\(key.stringValue) was not found, \(context.debugDescription)")
} catch DecodingError.typeMismatch(let type, let context) {
print("\(type) was expected, \(context.debugDescription)")
} catch DecodingError.valueNotFound(let type, let context) {
print("no value was found for \(type), \(context.debugDescription)")
} catch {
print("I know not this error")
}
But this is a lot of code to put everywhere I could encounter a decoding error. And, if my do{} block has multiple calls that throw, I may need to handle the errors that those methods call differently. The pattern I am trying to implement looks like this ... where decodingError(error) has all of the messy code above
do {
let object1 = try decoder.decode(SomeClass.self, from: someData)
try object2.methodThatThrowsSomeOtherError()
} catch <all decoding errors> { // this is invalid pseudocode
MyCentralLogger.log.decodingError(error)
} catch let nonDecodingError {
MyCentralLogger.log.error(nonDecodingError)
}
I can have a catch pattern like this that seems to satisfy all of the enumeration cases (at least it compiles)
} catch is DecodingError {
but the compiler doesn't seem to autobind the 'error' variable, and I don't see any option like
} catch let decodingError is DecodingError { // THIS IS NOT VALID
If I just catch all errors, I can easily have a switch in a central method that separates the different decoding error cases appropriately. But I want to be able to avoid sending non-decoding errors into that switch. I can also separate my do{} blocks so that I'm only performing decoding steps in it, but this also makes code messy, particularly if you are decoding multiple messages interspersed with other actions.
Suggestions? Thanks all!