Reputation: 1537
I'm starting to rewrite an application and I want to use Swift 4 Codable protocol to automatically convert json string to Objects and Structs.
Sometimes, specially at the beginning of coding, I encountered decoding problems, so I want to print these errors (whithout using always the debugger), in case some beans are not decoded correctly.
The problem is this:
As you can see, in the debugger, on "decodingError" object there is both:
My problem is that the only properties of that element, in the code, are errorDescription, failureReason, etc, that are ALL nil.
How can I print the values that are correctly displayed in the debugger?
Upvotes: 21
Views: 13995
Reputation: 9975
Fancy over the top pretty print that spills everything you wanted to know about the error:
do {
return try decoder.decode(...)
} catch let error as DecodingError {
print(error.prettyDescription)
}
private extension DecodingError {
var prettyDescription: String {
switch self {
case let .typeMismatch(type, context):
"DecodingError.typeMismatch \(type), value \(context.prettyDescription) @ ERROR: \(localizedDescription)"
case let .valueNotFound(type, context):
"DecodingError.valueNotFound \(type), value \(context.prettyDescription) @ ERROR: \(localizedDescription)"
case let .keyNotFound(key, context):
"DecodingError.keyNotFound \(key), value \(context.prettyDescription) @ ERROR: \(localizedDescription)"
case let .dataCorrupted(context):
"DecodingError.dataCorrupted \(context.prettyDescription), @ ERROR: \(localizedDescription)"
default:
"DecodingError: \(localizedDescription)"
}
}
}
private extension DecodingError.Context {
var prettyDescription: String {
var result = ""
if !codingPath.isEmpty {
result.append(codingPath.map(\.stringValue).joined(separator: "."))
result.append(": ")
}
result.append(debugDescription)
if
let nsError = underlyingError as? NSError,
let description = nsError.userInfo["NSDebugDescription"] as? String
{
result.append(description)
}
return result
}
}
Upvotes: 0
Reputation: 1899
catch let error as DecodingError {
switch error {
case .typeMismatch(let key, let value):
print("error \(key), value \(value) and ERROR: \(error.localizedDescription)")
case .valueNotFound(let key, let value):
print("error \(key), value \(value) and ERROR: \(error.localizedDescription)")
case .keyNotFound(let key, let value):
print("error \(key), value \(value) and ERROR: \(error.localizedDescription)")
case .dataCorrupted(let key):
print("error \(key), and ERROR: \(error.localizedDescription)")
default:
print("ERROR: \(error.localizedDescription)")
}
}
Upvotes: 35
Reputation: 285072
DecodingError
is an enum. In your case you have to catch
the typeMismatch
case and print the type
and the context
.
catch let DecodingError.typeMismatch(type, context) {
print("Type '\(type)' mismatch:", context.debugDescription)
print("codingPath:", context.codingPath)
}
Upvotes: 38