Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error handling using JSONDecoder in Swift

Tags:

json

swift

I am using JSONDecoder() in Swift and need to get better error messages.

Within the debug description (for example) I can see messages like "The given data was not valid JSON", but I need to know it is that rather than a network error (for example).

    let decoder = JSONDecoder()
    if let data = data{
        do {
            // process data

        } catch let error {
           // can access error.localizedDescription but seemingly nothing else
    }

I tried to cast to a DecodingError, but this does not seem to reveal more information. I certainly don't need the string - even an error code is much more helpful than this...

like image 435
WishIHadThreeGuns Avatar asked Mar 28 '19 03:03

WishIHadThreeGuns


People also ask

How do you throw an error in Swift?

To indicate that a function, method, or initializer can throw an error, you write the throws keyword in the function's declaration after its parameters. A function marked with throws is called a throwing function. If the function specifies a return type, you write the throws keyword before the return arrow ( -> ).

Do catch in Swift?

The try/catch syntax was added in Swift 2.0 to make exception handling clearer and safer. It's made up of three parts: do starts a block of code that might fail, catch is where execution gets transferred if any errors occur, and any function calls that might fail need to be called using try .


1 Answers

Never print error.localizedDescription in a decoding catch block. This returns a quite meaningless generic error message. Print always the error instance. Then you get the desired information.

let decoder = JSONDecoder()
    if let data = data {
        do {
            // process data

        } catch  {
           print(error)
    }

Or for the full set of errors use

let decoder = JSONDecoder()
if let data = data {
    do {
       // process data
    } catch let DecodingError.dataCorrupted(context) {
        print(context)
    } catch let DecodingError.keyNotFound(key, context) {
        print("Key '\(key)' not found:", context.debugDescription)
        print("codingPath:", context.codingPath)
    } catch let DecodingError.valueNotFound(value, context) {
        print("Value '\(value)' not found:", context.debugDescription)
        print("codingPath:", context.codingPath)
    } catch let DecodingError.typeMismatch(type, context)  {
        print("Type '\(type)' mismatch:", context.debugDescription)
        print("codingPath:", context.codingPath)
    } catch {
        print("error: ", error)
    }
like image 103
vadian Avatar answered Oct 30 '22 21:10

vadian