Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: improved deserialization failure output #774

Closed
cdaringe opened this issue Apr 12, 2024 · 2 comments
Closed

RFC: improved deserialization failure output #774

cdaringe opened this issue Apr 12, 2024 · 2 comments

Comments

@cdaringe
Copy link

cdaringe commented Apr 12, 2024

Problem

The generated client can fail during deserialization of json models, but it can be very challenging to discern why failure occurred.

Motivating Context

We modeled schema from a partner team that is, simply, very large. Maybe two dozen or so structs. It wouldn't deserialize, and we had no idea why.

Here's all we got:

Result::unwrap() on an Err value: Error("premature end of input", line: 1, column: 19)

As you can see, there's nothing about what specifically wouldn't deserialize. Turns out, it was about 5 layers deep, and it was a bad date deserializing. We have to do a binary search, serde skip ing fields of our schema, until we were able to isolate that naughty field.

Discussion

I asked in stack overflow, and they said "hey, there's this cool crate that decorates errors with paths that failed to deserialize".

TLDR, i think it may be nice to use that crate for its user friendly errors?

Anyway, i'm a noob, so unclear if this is the best or worst suggestion :)

@ahl
Copy link
Collaborator

ahl commented Apr 15, 2024

This is an interesting request. My initial reaction is to see if this is something that consumers can do on their own: we already have folks who want to see fewer dependencies and less code (oxidecomputer/typify#556).

For your use case, could you do something like this:

let response = client.operation().send().await;

match response {
    ..

    Err(progenitor::Error::InvalidResponsePayload(data, error) => {
        let x = &mut serde_json::Deserializer::from_reader(data.clone().reader());
        let result: Result<ExpectedType, _> = serde_path_to_error::deserialize(x);
        ..
    }
}

That may be awkward in that you need to know the return type. If that doesn't work for you, let me know and we can think about optional generation. In general, we've tried to avoid this as supporting multiple paths makes for more code to maintain and more cases to verify.

@cdaringe
Copy link
Author

Thank you for the thoughtful response. Will give it a whirl. Seems adequate, or perhaps trait-able :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants