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}