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. This type should only be used for debugging purposes or internal
10/// facing applications, as it includes the full error chain with descriptions,
11/// thus leaking information that could possibly be sensitive.
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, ErrorKind};
45
46    #[test]
47    fn internal_server_error() {
48        let response = InternalServerError(Error::new(ErrorKind::Other, "Test")).into_response();
49        assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR);
50    }
51}