rocket/response/debug.rs
1use crate::request::Request;
2use crate::response::{self, Responder};
3use crate::http::Status;
4
5use yansi::Paint;
6
7/// Debug prints the internal value before forwarding to the 500 error catcher.
8///
9/// This value exists primarily to allow handler return types that would not
10/// otherwise implement [`Responder`]. It is typically used in conjunction with
11/// `Result<T, E>` where `E` implements `Debug` but not `Responder`.
12///
13/// Note that because of it's common use as an error value, `std::io::Error`
14/// _does_ implement `Responder`. As a result, a `std::io::Result<T>` can be
15/// returned directly without the need for `Debug`:
16///
17/// ```rust
18/// use std::io;
19///
20/// # use rocket::get;
21/// use rocket::fs::NamedFile;
22///
23/// #[get("/")]
24/// async fn index() -> io::Result<NamedFile> {
25/// NamedFile::open("index.html").await
26/// }
27/// ```
28///
29/// # Example
30///
31/// Because of the generic `From<E>` implementation for `Debug<E>`, conversions
32/// from `Result<T, E>` to `Result<T, Debug<E>>` through `?` occur
33/// automatically:
34///
35/// ```rust
36/// use std::string::FromUtf8Error;
37///
38/// # use rocket::get;
39/// use rocket::response::Debug;
40///
41/// #[get("/")]
42/// fn rand_str() -> Result<String, Debug<FromUtf8Error>> {
43/// # /*
44/// let bytes: Vec<u8> = random_bytes();
45/// # */
46/// # let bytes: Vec<u8> = vec![];
47/// Ok(String::from_utf8(bytes)?)
48/// }
49/// ```
50///
51/// It is also possible to map the error directly to `Debug` via
52/// [`Result::map_err()`]:
53///
54/// ```rust
55/// use std::string::FromUtf8Error;
56///
57/// # use rocket::get;
58/// use rocket::response::Debug;
59///
60/// #[get("/")]
61/// fn rand_str() -> Result<String, Debug<FromUtf8Error>> {
62/// # /*
63/// let bytes: Vec<u8> = random_bytes();
64/// # */
65/// # let bytes: Vec<u8> = vec![];
66/// String::from_utf8(bytes).map_err(Debug)
67/// }
68/// ```
69#[derive(Debug)]
70pub struct Debug<E>(pub E);
71
72impl<E> From<E> for Debug<E> {
73 #[inline(always)]
74 fn from(e: E) -> Self {
75 Debug(e)
76 }
77}
78
79impl<'r, E: std::fmt::Debug> Responder<'r, 'static> for Debug<E> {
80 fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> {
81 warn_!("Debug: {:?}", self.0.primary());
82 warn_!("Debug always responds with {}.", Status::InternalServerError.primary());
83 Err(Status::InternalServerError)
84 }
85}
86
87/// Prints a warning with the error and forwards to the `500` error catcher.
88impl<'r> Responder<'r, 'static> for std::io::Error {
89 fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> {
90 warn_!("I/O Error: {:?}", self.primary());
91 Err(Status::InternalServerError)
92 }
93}