Warp: Can't use ? in async route handler

91 views Asked by At

I am trying to get an async handler working for a route using warp. I am doing some file operations with tokio. Here is a small example:

use tokio::fs::File;
use tokio::prelude::*;
use warp::Filter;

#[tokio::main]
async fn main() {
    let route = warp::path!("hello")
        .and_then( move || async move {
            let bin = File::open("test.txt").await?;
            Result::<warp::reply::Json, ServiceError>::Ok(warp::reply::json(vec!("1", "2")))
        });
}

#[derive(Debug)]
enum ServiceError{
    IoError(io::Error)
}
impl warp::reject::Reject for ServiceError {}
impl std::convert::From<std::io::Error> for ServiceError {
    fn from(error: io::Error) -> Self{
        ServiceError::IoError(error)
    }
}

You'll need:

[dependencies]
tokio = { version = "0.2", features = ["full", "fs"] }
warp = "0.2"

The error occurs at .and_then( move || async move {:

the trait bound `ServiceError: warp::reject::sealed::CombineRejection<warp::Rejection>` is not satisfied

This trait is sealed, so I couldn't implement it if I wanted to. I would have thought that implementing warp::reject::Reject for ServiceError would have been enough. I'm not sure how to get around this one.

I found this answer that offers a possible solution but I'd like to stay on the official releases if possible.

I really would like to use the ? if possible, and my research leads me to believe I can. Using map_error is apparently an alternative, but much more cumbersome, especially with multiple calls to async file functions.

0

There are 0 answers