WWDC22 SALE: Save 50% on all my Swift books and bundles! >>

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!

   

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.

1      

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

1      

What does missing key means?

   

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

   

Save 50% in my Black Friday sale.

SAVE 50% To celebrate WWDC22, all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

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

Reply to this topic…

You need to create an account or log in to reply.

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.