Skip to main content

axum_extra/response/
error_response.rs

1use axum_core::response::{IntoResponse, Response};
2use http::StatusCode;
3use std::error::Error;
4use tracing::error;
5
6/// Convenience response to create an error response from a non-[`IntoResponse`] error
7///
8/// This provides a method to quickly respond with an error that does not implement
9/// the `IntoResponse` trait itself. Error details are logged using [`tracing::error!`]
10/// and a generic `500 Internal Server Error` response is returned to the client without
11/// exposing error details.
12///
13/// ```rust
14/// use axum_extra::response::InternalServerError;
15/// use axum_core::response::IntoResponse;
16/// # use std::io::{Error, ErrorKind};
17/// # fn try_thing() -> Result<(), Error> {
18/// #   Err(Error::new(ErrorKind::Other, "error"))
19/// # }
20///
21/// async fn maybe_error() -> Result<String, InternalServerError<Error>> {
22///     try_thing().map_err(InternalServerError)?;
23///     // do something on success
24///     # Ok(String::from("ok"))
25/// }
26/// ```
27#[derive(Debug)]
28pub struct InternalServerError<T>(pub T);
29
30impl<T: Error + 'static> IntoResponse for InternalServerError<T> {
31    fn into_response(self) -> Response {
32        error!(error = &self.0 as &dyn Error);
33        (
34            StatusCode::INTERNAL_SERVER_ERROR,
35            "An error occurred while processing your request.",
36        )
37            .into_response()
38    }
39}
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44    use std::io::Error;
45
46    #[test]
47    fn internal_server_error() {
48        let response = InternalServerError(Error::other("Test")).into_response();
49        assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR);
50    }
51}