-
Bug ReportVersion
Platform
Crates
DescriptionWhen trying to use the // Cargo.toml
//
// [package]
// name = "mvp"
// version = "0.1.0"
// edition = "2021"
//
// [dependencies]
// axum = "0.8.4"
// axum-extra = "0.10.1"
// tokio = { version = "1.47.1", features = ["full"] }
// tower-http = { version = "0.6.6", features = ["trace"] }
use axum::{Router, routing};
use tower_http::trace::TraceLayer;
use axum_extra::middleware::option_layer;
#[tokio::main]
async fn main() {
let trace_layer = TraceLayer::new_for_http();
let app = Router::new()
.route("/", routing::get(|| async { "Hello, World!" }))
.layer(trace_layer)
.layer(option_layer(Some(trace_layer)));
//
// ^^ Expect this to work, but get following error. (Of course a dummy setup, but it should illustrate that the trace layer works without the option_layer wrapper).
//
// error[E0271]: type mismatch resolving `<Route as Service<Request<Body>>>::Response == Response<ResponseBody<Body, NeverClassifyEos<ServerErrorsFailureClass>>>`
// --> src/main.rs:12:10
// |
// 12 | .layer(option_layer(Some(trace_layer)));
// | ^^^^^ expected `Response<ResponseBody<..., ...>>`, found `Response<Body>`
// |
// = note: expected struct `Response<ResponseBody<Body, NeverClassifyEos<ServerErrorsFailureClass>>>`
// found struct `Response<Body>`
// = note: required for `Either<Trace<Route, SharedClassifier<ServerErrorsAsFailures>>, Route>` to implement `tower_service::Service<axum::http::Request<Body>>`
//
// For more information about this error, try `rustc --explain E0271`.
let listener = tokio::net::TcpListener::bind("0.0.0.0:3001").await.unwrap();
axum::serve(listener, app).await.unwrap();
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
Without testing the setup, what I think happens is that the trace layer changes the body type of the response, which the optional layer does not support though it doesn't seem to be documented. This doesn't work: let app = Router::new()
.layer(option_layer(Some(TraceLayer::new_for_http())))
.with_state(state); while this does: let app = Router::new()
.layer(option_layer(Some((
tower_http::map_response_body::MapResponseBodyLayer::new(axum::body::Body::new),
TraceLayer::new_for_http(),
))))
.with_state(state); What happens is By using a tuple as shown, it first applies the trace layer but then wraps it again in the same body, changing it back. |
Beta Was this translation helpful? Give feedback.
Without testing the setup, what I think happens is that the trace layer changes the body type of the response, which the optional layer does not support though it doesn't seem to be documented.
This doesn't work:
while this does:
What happens is
optinal_layer
createsEither<T, Idnetity>
which implementsLayer
but the returned service imple…