From 59623d936f3e1eaeb60976f702f093cc1bed7b23 Mon Sep 17 00:00:00 2001 From: Sergio Benitez Date: Fri, 7 Oct 2016 21:31:52 -0700 Subject: [PATCH] Add a default template for every known error code. --- lib/src/catcher.rs | 161 ++++++++++++++++++++++++++++++--------------- 1 file changed, 108 insertions(+), 53 deletions(-) diff --git a/lib/src/catcher.rs b/lib/src/catcher.rs index 1910bf0f..b772e1fd 100644 --- a/lib/src/catcher.rs +++ b/lib/src/catcher.rs @@ -20,19 +20,15 @@ pub struct Catcher { impl Catcher { pub fn new(code: u16, handler: ErrorHandler) -> Catcher { - Catcher::new_with_default(code, handler, false) + Catcher { code: code, handler: handler, is_default: false } } pub fn handle<'b, 'r>(&self, err: Error, request: &'b Request<'r>) -> Response<'b> { (self.handler)(err, request) } - fn new_with_default(code: u16, handler: ErrorHandler, default: bool) -> Catcher { - Catcher { - code: code, - handler: handler, - is_default: default, - } + fn new_default(code: u16, handler: ErrorHandler) -> Catcher { + Catcher { code: code, handler: handler, is_default: true, } } pub fn is_default(&self) -> bool { @@ -52,6 +48,48 @@ impl fmt::Display for Catcher { } } +macro_rules! error_page_template { + ($code:expr, $name:expr, $description:expr) => ( + concat!(r#" + + + + + "#, $code, " ", $name, r#" + + +
+

"#, $code, " ", $name, r#" +

"#, $description, r#"

+
+ Rocket +

+ + + "# + ) + ) +} + +macro_rules! default_errors { + ($($code:expr, $name:expr, $description:expr, $fn_name:ident),+) => ( + let mut map = HashMap::new(); + + $( + fn $fn_name<'r>(_: Error, _r: &'r Request) -> Response<'r> { + Response::with_status( + StatusCode::Unregistered($code), + data::HTML(error_page_template!($code, $name, $description)) + ) + } + + map.insert($code, Catcher::new_default($code, $fn_name)); + )+ + + map + ) +} + pub mod defaults { use super::Catcher; @@ -63,52 +101,69 @@ pub mod defaults { use error::Error; use http::hyper::StatusCode; - pub fn not_found<'r>(_error: Error, _request: &'r Request) -> Response<'r> { - Response::with_status(StatusCode::NotFound, data::HTML(r#" - - - - - 404: Not Found - - -
-

404: Not Found

-

The page you were looking for could not be found.

-


- Rocket -
- - - "#)) - } - - pub fn internal_error<'r>(_error: Error, - _request: &'r Request) - -> Response<'r> { - Response::with_status(StatusCode::InternalServerError, data::HTML(r#" - - - - - 500: Internal Server Error - - -
-

500: Internal Server Error

-

The server encountered a problem processing your request.

-


- Rocket -
- - - "#)) - } - pub fn get() -> HashMap { - let mut map = HashMap::new(); - map.insert(404, Catcher::new_with_default(404, not_found, true)); - map.insert(500, Catcher::new_with_default(500, internal_error, true)); - map + default_errors! { + 400, "Bad Request", "The request could not be understood by the server due + to malformed syntax.", handle_400, + 401, "Unauthorized", "The request requires user authentication.", + handle_401, + 403, "Forbidden", "The request was forbidden by the server. + Check authentication.", handle_403, + 402, "Payment Required", "The request could not be processed due to lack of + payment.", handle_402, + 404, "Not Found", "The requested resource could not be found.", handle_404, + 405, "Method Not Allowed", "The request method is not supported for the + requested resource.", handle_405, + 406, "Not Acceptable", "The requested resource is capable of generating + only content not acceptable according to the Accept headers sent in the + request.", handle_406, + 407, "Proxy Authentication Required", "Authentication with the proxy is + required.", handle_407, + 408, "Request Timeout", "The server timed out waiting for the + request.", handle_408, + 409, "Conflict", "The request could not be processed because of a conflict + in the request.", handle_409, + 410, "Gone", "The resource requested is no longer available and will not be + available again.", handle_410, + 411, "Length Required", "The request did not specify the length of its + content, which is required by the requested resource.", handle_411, + 412, "Precondition Failed", "The server does not meet one of the + preconditions specified in the request.", handle_412, + 413, "Payload Too Large", "The request is larger than the server is + willing or able to process.", handle_413, + 414, "URI Too Long", "The URI provided was too long for the server to + process.", handle_414, + 415, "Unsupported Media Type", "The request entity has a media type which + the server or resource does not support.", handle_415, + 416, "Range Not Satisfiable", "The portion of the requested file cannot be + supplied by the server.", handle_416, + 417, "Expectation Failed", "The server cannot meet the requirements of the + Expect request-header field.", handle_417, + 418, "I'm a teapot", "I was requested to brew coffee, and I am a + teapot.", handle_418, + 421, "Misdirected Request", "The server cannot produce a response for this + request.", handle_421, + 426, "Upgrade Required", "Switching to the protocol in the Upgrade header + field is required.", handle_426, + 428, "Precondition Required", "The server requires the request to be + conditional.", handle_428, + 429, "Too Many Requests", "Too many requests have been received + recently.", handle_429, + 431, "Request Header Fields Too Large", "The server is unwilling to process + the request because either an individual header field, or all + the header fields collectively, are too large.", handle_431, + 451, "Unavailable For Legal Reasons", "The requested resource is + unavailable due to a legal demand to deny access to this + resource.", handle_451, + 500, "Internal Server Error", "The server encountered an internal error + while processing this request.", handle_500, + 501, "Not Implemented", "The server either does not recognize the request + method, or it lacks the ability to fulfill the request.", handle_501, + 503, "Service Unavailable", "The server is currently unavailable.", + handle_503, + 510, "Not Extended", "Further extensions to the request are required for + the server to fulfill it.", handle_510 + } } } +