Search code examples
swiftexceptionjsondecoder

Swift: Can't catch specific error case with associated data


I am setting a custom JSONDecoder.dateDecodingStrategy that throws a DecodingError.dataCorruptedError if a date isn't formatted correctly:

decoder.dateDecodingStrategy = .custom { (decoder) -> Date in
    let container = try decoder.singleValueContainer()
    let dateString = try container.decode(String.self)
    let date = /* do magic date manipulation here */

    if let date = date {
        return date
    } else {
        throw DecodingError.dataCorruptedError(in: container,
                                               debugDescription: "foo")
    }
}

However, I can't seem to write a catch clause for this specific DecodingError type. I've tried

} catch DecodingError.dataCorruptedError(let container, let debugDescription) {

and

} catch DecodingError.dataCorruptedError(_, _) {

both of which state that "Argument labels '(_:, _:)' do not match any available overloads."

Leaving out the associated data altogether, like

} catch DecodingError.dataCorruptedError {

barfs with "Expression pattern of type '_' cannot match values of type 'Error'."

So I tried a different tack, namely

} catch let error as DecodingError {
    switch error {
    case .dataCorruptedError(_, _):

but this also fails to compile, stating "Pattern cannot match values of type 'DecodingError'."

Surely I'm missing something very simple, but what?


Solution

  • DecodingError.dataCorruptedError(in:debugDescription:) is a static function over DecodingError, and this function returns the .dataCorrupted case. Thus, you catch statement should look like this:

    } catch DecodingError.dataCorrupted(let context) {
    

    You should be able to extract some information from the context, if you need more then you might need a dedicated type of error.