[RESOLVED] Error handling with Futures

I am writing a library to access an HTTP API asynchronous using hyper and Futures.
There is this one thing that I just can’t wrap my head around: How to deal with errors before even starting the request / spawning the Future.

Here is an example of how I am writing the client implementation:

pub fn get(self) -> impl Future<Item = Component, Error = Error> {
    let result = doing_some_checks();
    if result.is_error() {
        // The following obviously won't work:
        return Err(Error::SomeErrorKind);

    // safe to use
    let something = result.unwrap();
    let request = ... // creating hyper request

        .request(request) // returns a Future
        .and_then(|response| {
            // doing stuff with the response ...

Is there any way to deal with errors before doing the HTTP request? It will have to do with returning some kind of an ‘error’ Future, but I could not find a working solution so far, a simple return futures::future::err(Error::ErrorKind) won’t work.

1 Like

Call this function: https://docs.rs/futures/0.2.1/futures/future/fn.err.html

fn get(self) -> Box<dyn Future<Item = Component, Error = Error>> {
    if let Err(e) = result {
        return Box::new(futures::future::err(somehow_convert_error_type(e)));

The important thing is using a Boxed trait object in comparison to impl Trait.
You can not return two different types in two control flow paths from one impl Trait returning function.

You might want to read this: https://github.com/rust-lang/rfcs/blob/master/text/2113-dyn-trait-syntax.md

Great, that helped a lot! Boxing seems like a good thing to do.
Thank you!

If you didn’t want to box, you could use the futures::future::Either enum to allow two different types. The signature would look like:

fn get(self) -> Either<impl Future<Item=Component, Error=Error>, impl Future<Item=Component, Error=Error>> {...}