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.