Skip to main content

quokka_handler/
error.rs

1use axum::response::IntoResponse;
2
3#[derive(Clone)]
4pub struct Error {
5    pub debug: String,
6    pub message: String,
7}
8
9pub type Result<T> = std::result::Result<T, Error>;
10
11impl Error {
12    pub fn new(message: impl ToString) -> Self {
13        Self {
14            message: message.to_string(),
15            debug: message.to_string(),
16        }
17    }
18
19    ///
20    /// Wraps any printable error, with the debug output in the debug field
21    ///
22    /// # Tests
23    ///
24    /// ```
25    /// let error = quokka_handler::Error::wrap("A test error")(quokka_handler::Error::new("Test Error"));
26    /// let message = format!("{}", error);
27    /// let debug = format!("{:?}", error);
28    ///
29    /// assert_eq!(message, "A test error");
30    /// assert_eq!(debug, "Test Error");
31    /// ```
32    ///
33    #[tracing::instrument(skip(message))]
34    pub fn wrap<E: std::error::Error>(message: impl ToString) -> impl FnOnce(E) -> Self {
35        let message = message.to_string();
36
37        move |error| Self {
38            message,
39            debug: format!("{error:?}"),
40        }
41    }
42
43    ///
44    /// Wraps any printable error, with the debug output in the debug field
45    ///
46    /// # Tests
47    ///
48    /// ```
49    /// #[tokio::main]
50    /// async fn main() {
51    /// let error = quokka_handler::Error::wrap_response(String::from("A test error")).await;
52    /// let message = format!("{}", error);
53    ///
54    /// assert_eq!(message, "A test error");
55    /// }
56    /// ```
57    ///
58    #[tracing::instrument(skip(response))]
59    pub async fn wrap_response(response: impl IntoResponse) -> Self {
60        let error = axum::body::to_bytes(response.into_response().into_body(), 1024)
61            .await
62            .map(|bytes| String::from_utf8_lossy(&bytes).to_string())
63            .map_err(Self::wrap("Unable to get response body to string"))
64            .map(Self::new);
65
66        match error {
67            Ok(err) => err,
68            Err(err) => err,
69        }
70    }
71}
72
73impl std::error::Error for Error {}
74
75///
76/// # Tests
77///
78/// ```
79/// let error = format!("{:?}", quokka_handler::Error { message: String::new(), debug: String::from("Test Debug") });
80///
81/// assert_eq!(error, "Test Debug");
82/// ```
83///
84impl std::fmt::Display for Error {
85    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
86        f.write_str(&self.message)
87    }
88}
89
90///
91/// # Tests
92///
93/// ```
94/// let error = format!("{}", quokka_handler::Error::new("Test Error"));
95///
96/// assert_eq!(error, "Test Error");
97/// ```
98///
99impl std::fmt::Debug for Error {
100    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101        f.write_str(&self.debug)
102    }
103}
104
105impl From<quokka_templating::Error> for Error {
106    fn from(value: quokka_templating::Error) -> Self {
107        Self {
108            debug: format!("{value:?}"),
109            message: value.to_string(),
110        }
111    }
112}