Help with reqwest.json()? and custom errors

#1

Hello everybody, first post and new rust project at work! :partying_face: So, naive alert here!! :crazy_face:

I’m trying to implement the custom error wrapping described here:
https://doc.rust-lang.org/rust-by-example/error/multiple_error_types/wrap_error.html looks like a very good and scalable way to deal with error handling (not so easy for a rust newcomer).

I have a function that calls an external service with reqwest and try to deserialize the result in a custom type. Here it is:

fn fetch_person(id: i32) -> SwapiResult<SwapiPerson> {
    let url = format!("https://swapi.co/api/people/{}", id);
    reqwest::get(&url)?.json()?
}

SwapiResult is defined like this:

type SwapiResult<T> = Result<T, SwapiError>;

and SwapiError is an enum modeled like the one in the guide above.

The compiler is telling me that I should implement the deserialize trait on the error. It’s not clear to me why it’s trying to deserialize the body of the response into an error, instead of just returning the Err(reqwest::Error) converted in a SwapiError.

this is the error I’m getting:

error[E0277]: the trait bound `controller::person::SwapiError: models::_IMPL_SERIALIZE_FOR_Person::_serde::Deserialize<'_>` is not satisfied
  --> src/controller/person.rs:66:25
   |
66 |     reqwest::get(&url)?.json()?
   |                         ^^^^ the trait `models::_IMPL_SERIALIZE_FOR_Person::_serde::Deserialize<'_>` is not implemented for `controller::person::SwapiError`
   |
   = note: required because of the requirements on the impl of `for<'de> models::_IMPL_SERIALIZE_FOR_Person::_serde::Deserialize<'de>` for `std::result::Result<swapi_models::person::Person, controller::person::SwapiError>`
   = note: required because of the requirements on the impl of `models::_IMPL_SERIALIZE_FOR_Person::_serde::de::DeserializeOwned` for `std::result::Result<swapi_models::person::Person, controller::person::SwapiError>`

What’s the problem here? Many thanks in advance!

#2

You’re fetching SwapiPerson, but your function needs to return SwapiResult, so return Ok(reqwest::get(….

You get this weird error, because .json() works “backwards” from the return type, and it sees it’s asked to give you SwapiResult, but it doesn’t know how.

1 Like
#3

but…isn’t the ? responsible for wrapping everything in a Result?

#4

No, ? is the opposite. It removes things out of a Result<T, …> to bare T.

1 Like
#5

thanks, it’s working…I’m feeling stupid :sweat_smile:

#6

No problem.