NRitH
NRitH

Reputation: 13893

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?

Upvotes: 1

Views: 1403

Answers (2)

Cristik
Cristik

Reputation: 32817

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.

Upvotes: 2

SIlvester
SIlvester

Reputation: 770

The reason why you are getting "Pattern cannot match values of type 'DecodingError'." error (and other) is that .dataCorruptedError(_, _) is not an enum case but static function:

public static func dataCorruptedError(in container: UnkeyedDecodingContainer, debugDescription: String) -> DecodingError

To handle DataCorrupted error in switch you need to use available enum case for it, for example like that:

catch let error as DecodingError {
    switch error {
    case .dataCorrupted:
        debugPrint("Data corrupted Custom Message")
    default: ()
    }
}

Upvotes: 1

Related Questions