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