routing with closures rather than async fn
#2330
-
Hi - first, it's me, not you :-), but I don't know why it's me. I'm converting a tide web app to Axum and there are 50 odd routes, each of which is a closure on the main app: let mut app = tide::new();
app.at("/xyz/something")
.post(|mut req: Request<()>| async move {
let result = ...;
json_and_cors_it_up(result)
});
app.at("/xyz/something-else")
.post(|mut req: Request<()>| async move {
let result = ...;
json_and_cors_it_up(result)
}); I've tried to use each closure as a handler: let mut app = Router::new().route(
"/xyz/something",
post(
|TypedHeader(context): TypedHeader<RequestContext>, Json(filter): Json<UIState>| -> anyhow::Result<dyn IntoResponse> {
async {
let result = ...;
json_and_cors_it_up(result)
}
},
),
).route(
"/xyz/something-else",
post(
|TypedHeader(context): TypedHeader<RequestContext>, Json(filter): Json<UIState>| -> anyhow::Result<dyn IntoResponse> {
async {
let result = ...;
json_and_cors_it_up(result)
}
},
),
);
fn json_and_cors_it_up<T>(result: T) -> anyhow::Result<impl IntoResponse>
where
T: serde::Serialize,
{
let json = serde_json::to_string_pretty(&result)?;
let response = (
StatusCode::OK,
[
(header::CONTENT_TYPE, "application/json"),
(header::ACCESS_CONTROL_ALLOW_ORIGIN, "*"),
],
json,
);
Ok(response)
} but I'm getting the error: error[E0308]: mismatched types
--> dashboard_backend_server/src/main.rs:1007:21
|
1007 | / async {
1008 | | let filter = sanitise(&context, filter)
1009 | | .await
1010 | | .expect("cannot sanitise filter");
... |
1013 | | json_and_cors_it_up(result)
1014 | | }
| |_____________________^ expected `Result<dyn IntoResponse, Error>`, found `async` block
...
1031 | fn json_and_cors_it_up<T>(result: T) -> anyhow::Result<impl IntoResponse>
| ----------------- the found opaque type
|
= note: expected enum `Result<dyn IntoResponse, anyhow::Error>`
found `async` block `{async block@dashboard_backend_server/src/main.rs:1007:21: 1014:22}`
error[E0277]: the trait bound `{closure@dashboard_backend_server/src/main.rs:1004:17: 1006:53}: Handler<_, _, _>` is not satisfied
--> dashboard_backend_server/src/main.rs:1004:17
|
1003 | post(
| ---- required by a bound introduced by this call
1004 | / |TypedHeader(context): TypedHeader<RequestContext>,
1005 | | extract::Json(filter): extract::Json<dashboard_api::filter::UIState>|
1006 | | -> anyhow::Result<dyn IntoResponse> {
1007 | | async {
... |
1014 | | }
1015 | | },
| |_________________^ the trait `Handler<_, _, _>` is not implemented for closure `{closure@dashboard_backend_server/src/main.rs:1004:17: 1006:53}`
|
= help: the following other types implement trait `Handler<T, S, B>`:
<Layered<L, H, T, S, B, B2> as Handler<T, S, B2>>
<MethodRouter<S, B> as Handler<(), S, B>>
note: required by a bound in `post`
--> /Users/coliny/.cargo/registry/src/index.crates.io-6f17d22bba15001f/axum-0.6.20/src/routing/method_routing.rs:407:1
|
407 | top_level_handler_fn!(post, POST);
| ^^^^^^^^^^^^^^^^^^^^^^----^^^^^^^
| | |
| | required by a bound in this function
| required by this bound in `post`
= note: this error originates in the macro `top_level_handler_fn` (in Nightly builds, run with -Z macro-backtrace for more info) Any suggestions? Thanks! |
Beta Was this translation helpful? Give feedback.
Answered by
davidpdrsn
Nov 20, 2023
Replies: 1 comment
-
anyhow::Error doesn’t implement IntoResponse. You have to make a wrapper that does. |
Beta Was this translation helpful? Give feedback.
0 replies
Answer selected by
yatesco
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
anyhow::Error doesn’t implement IntoResponse. You have to make a wrapper that does.