How to create a global/catch-all error #2266
-
Hi, The reason i wanted to implement this is because i found an error when writing the route, if i put the layer and routes in the wrong order, when hitting the api i'll be getting some error with like Here's my current code, for context // main.rs
async fn server() {
let connection_string = (utils::constants::DATABASE_URL).clone();
let db: DatabaseConnection = Database::connect(connection_string).await.unwrap();
init_cron();
tracing_subscriber::fmt().with_target(false).init();
let app: Router = Router::new()
.route("/", get(|| async {}))
.merge(routes::user::routes())
.merge(routes::expenses::routes())
.route_layer(middleware::from_fn(utils::guards::guard))
.merge(routes::expenses::routes())
.merge(routes::auth::routes())
.layer(Extension(db))
.layer(
TraceLayer::new_for_http()
.make_span_with(trace::DefaultMakeSpan::new().level(Level::INFO))
.on_response(trace::DefaultOnResponse::new().level(Level::INFO)),
)
.fallback(handler_404);
// wanted to add the catch-all error handler here
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
tracing::info!("listening on {}", addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap()
}
async fn handler_404() -> impl IntoResponse {
(
StatusCode::NOT_FOUND,
"The requested resource was not found",
)
} // error.rs
use axum::{
http::{header, StatusCode, Method, Uri},
response::IntoResponse,
Json, BoxError,
};
use serde_json::json;
use tower::timeout::error::Elapsed;
pub struct APIError {
pub message: String,
pub status_code: StatusCode,
pub error_code: Option<i8>,
}
impl IntoResponse for APIError {
fn into_response(self) -> axum::response::Response {
let status_code = self.status_code;
(status_code,
[(header::CONTENT_TYPE, "application/json")],
Json(json!({"StatusCode": self.status_code.as_u16(), "ErrorCode": self.error_code, "Message": self.message}))
).into_response()
}
} this is the example i'm trying to duplicate function errorHandler (err, req, res, next) {
res.status(500)
res.render('error', { error: err })
} would appreciate any help, thanks! |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
I am in the same boat as yours. Looking to find a way to have a global middleware. |
Beta Was this translation helpful? Give feedback.
-
axum currently doesn’t have a way catch any possible error. See https://github.com/tokio-rs/axum/tree/main/examples/customize-extractor-error for how to customize the response of extractors. Generally you shouldn’t need to customize the response from Extension because that error should never reach the end user. That is always a programmer error that should be caught by your automated tests. Id also recommend using https://docs.rs/axum/0.6.20/axum/struct.Router.html#method.with_state instead of Extension. |
Beta Was this translation helpful? Give feedback.
axum currently doesn’t have a way catch any possible error.
See https://github.com/tokio-rs/axum/tree/main/examples/customize-extractor-error for how to customize the response of extractors.
Generally you shouldn’t need to customize the response from Extension because that error should never reach the end user. That is always a programmer error that should be caught by your automated tests.
Id also recommend using https://docs.rs/axum/0.6.20/axum/struct.Router.html#method.with_state instead of Extension.