UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: Day 40: How to further identify decode error

Forums > 100 Days of SwiftUI

Hello!

I'm on project #8 and I'm super fascinated by decoders!

I was experiementing here and there, and I tried getting rid of the "id" for one of the austronauts in the .json file (corrupting the file on purpose).

As expected, I get a Moonshot/Bundle-Decodable.swift:29: Fatal error: Failed to decode astronauts.json from bundle error. However, it doesn't give any specifics on where exactly the error occrued! (I kind of expected Swift to explain where in the json file it failed to decode, but I don't see any line numbers.)

I imaigne there would this kind of "corrupt file" errors quite often in real-world applications, so I was curious if there are better ways to debug! Thank you in advance!

1      

Do-Catch combination will give you more options on the error.

Try replacing

guard let loaded = try? decoder.decode(T.self, from: data) else {
    fatalError("Failed to decode \(file) from bundle.")
}

return loaded

with

do {
    let loaded = try decoder.decode(T.self, from: data)
    return loaded
} catch {
    fatalError("Failed to decode \(file) from bundle. Error: \(error)")
}

You can do a similar change to the other guard let statements.

guard let is useful when you don't care about the details of the error (type, path, etc.) just that an error has occurred.

2      

hi,

agree with @Greenamberred, of course; but Paul also has an extended version of his func decode extension on Bundle that might give a little more information on an error during decoding. try using this one:

    func decode<T: Decodable>(from filename: String) -> T {

        guard let url = Bundle.main.url(forResource: filename, withExtension: nil) else {
            fatalError("Failed to locate \(filename) in app bundle.")
        }

        guard let data = try? Data(contentsOf: url) else {
            fatalError("Failed to load \(filename) in app bundle.")
        }

        let decoder = JSONDecoder()
        do {
            return try decoder.decode(T.self, from: data)
        } catch DecodingError.keyNotFound(let key, let context) {
            fatalError("Failed to decode \(filename) from bundle due to missing key '\(key.stringValue)' not found – \(context.debugDescription)")
        } catch DecodingError.typeMismatch(_, let context) {
            fatalError("Failed to decode \(filename) from bundle due to type mismatch – \(context.debugDescription)")
        } catch DecodingError.valueNotFound(let type, let context) {
            fatalError("Failed to decode \(filename) from bundle due to missing \(type) value – \(context.debugDescription)")
        } catch DecodingError.dataCorrupted(_) {
            fatalError("Failed to decode \(filename) from bundle because it appears to be invalid JSON")
        } catch {
            fatalError("Failed to decode \(filename) from bundle: \(error.localizedDescription)")
        }
    }

of course, if you have invalid JSON to start with, you may still just get a "fail to decode."

hope that helps,

DMG

4      

What does missing key means?

1      

hi,

you should get a DecodingError.keyNotFound error code if your struct or class object has defined a property, e.g., var total: Int, but the JSON you are reading has no matching entry for "total", i.e., the JSON should have an entry such as "total" : 99.

(note: if you have an optional property, such as var total: Int?, JSON will not throw this error if there's no matching entry ... you'll get a proper nil value in this case.)

the definitions for all the cases can be found in the documentation under DecodingError.

hope that helps,

DMG

1      

Hacking with Swift is sponsored by RevenueCat

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.