w_error), ); // handle errors by converting them into something that implements // `IntoResponse` async fn handle_anyhow_error(err: anyhow::Error) -> (StatusCode, String) { ( StatusCode::INTERNAL_SERVER_ERROR, format!("Something went wrong: {err}"), ) } # let _: Router = app; ``` # Applying fallible middleware Similarly axum requires you to handle errors from middleware. That is done with [`HandleErrorLayer`]: ```rust use axum::{ Router, BoxError, routing::get, http::StatusCode, error_handling::HandleErrorLayer, }; use std::time::Duration; use tower::ServiceBuilder; let app = Router::new() .route("/", get(|| async {})) .layer( ServiceBuilder::new() // `timeout` will produce an error if the handler takes // too long so we must handle those .layer(HandleErrorLayer::new(handle_timeout_error)) .timeout(Duration::from_secs(30)) ); async fn handle_timeout_error(err: BoxError) -> (StatusCode, String) { if err.is::() { ( StatusCode::REQUEST_TIMEOUT, "Request took too long".to_string(), ) } else { ( StatusCode::INTERNAL_SERVER_ERROR, format!("Unhandled internal error: {err}"), ) } } # let _: Router = app; ``` # Running extractors for error handling `HandleErrorLayer` also supports running extractors: ```rust use axum::{ Router, BoxError, routing::get, http::{StatusCode, Method, Uri}, error_handling::HandleErrorLayer, }; use std::time::Duration; use tower::ServiceBuilder; let app = Router::new() .route("/", get(|| async {})) .layer( ServiceBuilder::new() // `timeout` will produce an error if the handler takes // too long so we must handle those .layer(HandleErrorLayer::new(handle_timeout_error)) .timeout(Duration::from_secs(30)) ); async fn handle_timeout_error( // `Method` and `Uri` are extractors so they can be used here method: Method, uri: Uri, // the last argument must be the error itself err: BoxError, ) -> (StatusCode, String) { ( StatusCode::INTERNAL_SERVER_ERROR, format!("`{method} {uri}` failed with {err}"), ) } # let _: Router = app; ``` [`tower::Service`]: `tower::Service` [`Infallible`]: std::convert::Infallible [`Response`]: crate::response::Response [`IntoResponse`]: crate::response::IntoResponse