Hi there,
I have an issue while using warp:
async fn customize_error(err: Rejection) -> Result<impl Reply, Infallible> {
let code;
let message;
if let Some(server_error) = err.find::<error::ServerError>() {
code = StatusCode::INTERNAL_SERVER_ERROR;
message = server_error.msg.to_owned();
} else {
code = StatusCode::INTERNAL_SERVER_ERROR;
message = "UNHANDLED_REJECTION".to_string();
}
Ok(warp::reply::with_status(message, code))
}
#[tokio::main]
async fn main() {
let get_endpoint =
warp::path("endpoint")
.and(warp::query())
.map(move |params: HashMap<String, String>| {
get_endpoint_fn(¶ms)
.and_then(|response| Ok(response))
.or_else(|e| Err(warp::reject::custom(e.into())))
});
let get_routes = warp::get().and(get_endpoint).recover(customize_error);
let post_login = warp::path("login")
.and(warp::path::end())
.and(warp::body::form())
.map(|params: HashMap<String, String>| {
post_login_fn(¶ms)
.and_then(|response| Ok(response))
.or_else(|e| Err(warp::reject::custom(e.into())))
});
let post_routes = warp::post().and(post_login).recover(customize_error);
let routes = get_routes.or(post_routes);
warp::serve(routes).run(([127, 0, 0, 1], 4321)).await;
}
// error.rs
#[derive(Debug, Clone, Error, Serialize, PartialEq)]
pub struct ServerError {
#[serde(skip)]
pub status: StatusCode,
pub msg: String,
}
impl Reject for ServerError {}
impl Display for ServerError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{} ({})", self.msg, self.status)
}
}
impl ServerError {
pub fn new(status: StatusCode, msg: &str) -> Self {
ServerError {
status,
msg: msg.to_owned(),
}
}
}
impl From<anyhow::Error> for ServerError {
fn from(err: anyhow::Error) -> Self {
let e = match err.downcast::<ServerError>() {
Ok(e) => return e,
Err(e) => e,
};
ServerError::new(
StatusCode::INTERNAL_SERVER_ERROR,
&format!("Unhandled error type: {:#?}", e),
)
}
}
this doesn't build:
error[E0271]: type mismatch resolving `<warp::filter::recover::Recover<warp::filter::and::And<impl warp::filter::Filter+std::marker::Copy, warp::filter::map::Map<warp::filter::and::And<warp::filters::path::Exact<warp::filters::path::internal::Opaque<&str>>, impl warp::filter::Filter+std::marker::Copy>, [closure@src\main.rs:55:18: 64:14 get_auth_cfg_no_cookie:_]>>, fn(warp::reject::Rejection) -> impl core::future::future::Future {customize_error}> as warp::filter::FilterBase>::Error == warp::reject::Rejection`
--> src\main.rs:103:29
|
103 | let routes = get_routes.or(post_routes);
| ^^ expected enum `std::convert::Infallible`, found struct `warp::reject::Rejection`
error[E0277]: the trait bound `std::result::Result<impl warp::reply::Reply, warp::reject::Rejection>: warp::reply::Reply` is not satisfied
--> src\main.rs:106:17
|
106 | warp::serve(routes)
| ^^^^^^ the trait `warp::reply::Reply` is not implemented for `std::result::Result<impl warp::reply::Reply, warp::reject::Rejection>`
|
::: C:\Users\geobe\.cargo\registry\src\github.com-1ecc6299db9ec823\warp-0.2.2\src\server.rs:25:17
|
25 | F::Extract: Reply,
| ----- required by this bound in `warp::server::serve`
|
= help: the following implementations were found:
<std::result::Result<T, http::error::Error> as warp::reply::Reply>
= note: required because of the requirements on the impl of `warp::reply::Reply` for `(std::result::Result<impl warp::reply::Reply, warp::reject::Rejection>,)`
= note: required because of the requirements on the impl of `warp::reply::Reply` for `warp::generic::Either<(std::result::Result<impl warp::reply::Reply, warp::reject::Rejection>,), (impl warp::reply::Reply,)>`
= note: required because of the requirements on the impl of `warp::reply::Reply` for `(warp::generic::Either<(std::result::Result<impl warp::reply::Reply, warp::reject::Rejection>,), (impl warp::reply::Reply,)>,)`
= note: required because of the requirements on the impl of `warp::reply::Reply` for `warp::generic::Either<(warp::generic::Either<(std::result::Result<impl warp::reply::Reply, warp::reject::Rejection>,), (impl warp::reply::Reply,)>,), (warp::generic::Either<(std::result::Result<impl warp::reply::Reply, warp::reject::Rejection>,), (impl warp::reply::Reply,)>,)>`
= note: required because of the requirements on the impl of `warp::reply::Reply` for `(warp::generic::Either<(warp::generic::Either<(std::result::Result<impl warp::reply::Reply, warp::reject::Rejection>,), (impl warp::reply::Reply,)>,), (warp::generic::Either<(std::result::Result<impl warp::reply::Reply, warp::reject::Rejection>,), (impl warp::reply::Reply,)>,)>,)`
the two *_fn function return anyhow::Result<impl Reply>
and I have an impl From<anyhow::Error> for ServerError
and impl Reject for ServerError
Thank you for any insight