diff --git a/codegen/src/decorators/error.rs b/codegen/src/decorators/catch.rs similarity index 76% rename from codegen/src/decorators/error.rs rename to codegen/src/decorators/catch.rs index e48c46b7..ccd0dcb6 100644 --- a/codegen/src/decorators/error.rs +++ b/codegen/src/decorators/catch.rs @@ -1,5 +1,5 @@ use ::{CATCH_STRUCT_PREFIX, CATCH_FN_PREFIX, CATCHER_ATTR}; -use parser::ErrorParams; +use parser::CatchParams; use utils::*; use syntax::codemap::{Span}; @@ -11,21 +11,21 @@ use syntax::parse::token; const ERR_PARAM: &'static str = "__err"; const REQ_PARAM: &'static str = "__req"; -trait ErrorGenerateExt { +trait CatchGenerateExt { fn generate_fn_arguments(&self, &ExtCtxt, Ident, Ident) -> Vec; } -impl ErrorGenerateExt for ErrorParams { +impl CatchGenerateExt for CatchParams { fn generate_fn_arguments(&self, ecx: &ExtCtxt, err: Ident, req: Ident) -> Vec { - let arg_help = "error handlers can take either a `rocket::Error` or \ + let arg_help = "error catchers can take either a `rocket::Error`, \ `rocket::Request` type, or both."; // Retrieve the params from the user's handler and check the number. let input_args = &self.annotated_fn.decl().inputs; if input_args.len() > 2 { let sp = self.annotated_fn.span(); - ecx.struct_span_err(sp, "error handlers can have at most 2 arguments") + ecx.struct_span_err(sp, "error catchers can have at most 2 arguments") .help(arg_help).emit() } @@ -35,8 +35,10 @@ impl ErrorGenerateExt for ErrorParams { TyKind::Rptr(..) => Some(req), TyKind::Path(..) => Some(err), _ => { - ecx.struct_span_err(ty.span, "unexpected error handler argument") - .help(arg_help).emit(); + ecx.struct_span_err(ty.span, "unknown error catcher argument") + .help(arg_help) + .emit(); + None } } @@ -46,24 +48,24 @@ impl ErrorGenerateExt for ErrorParams { } } -pub fn error_decorator(ecx: &mut ExtCtxt, - sp: Span, - meta_item: &MetaItem, - annotated: Annotatable) - -> Vec -{ +pub fn catch_decorator( + ecx: &mut ExtCtxt, + sp: Span, + meta_item: &MetaItem, + annotated: Annotatable +) -> Vec { let mut output = Vec::new(); - // Parse the parameters from the error annotation. - let error = ErrorParams::from(ecx, sp, meta_item, &annotated); + // Parse the parameters from the `catch` annotation. + let catch = CatchParams::from(ecx, sp, meta_item, &annotated); // Get all of the information we learned from the attribute + function. - let user_fn_name = error.annotated_fn.ident(); + let user_fn_name = catch.annotated_fn.ident(); let catch_fn_name = user_fn_name.prepend(CATCH_FN_PREFIX); - let code = error.code.node; + let code = catch.code.node; let err_ident = Ident::from_str(ERR_PARAM); let req_ident = Ident::from_str(REQ_PARAM); - let fn_arguments = error.generate_fn_arguments(ecx, err_ident, req_ident); + let fn_arguments = catch.generate_fn_arguments(ecx, err_ident, req_ident); // Push the Rocket generated catch function. emit_item(&mut output, quote_item!(ecx, @@ -78,7 +80,7 @@ pub fn error_decorator(ecx: &mut ExtCtxt, } ).expect("catch function")); - // Push the static catch info. This is what the errors! macro refers to. + // Push the static catch info. This is what the `catchers!` macro refers to. let struct_name = user_fn_name.prepend(CATCH_STRUCT_PREFIX); emit_item(&mut output, quote_item!(ecx, #[allow(non_upper_case_globals)] diff --git a/codegen/src/decorators/mod.rs b/codegen/src/decorators/mod.rs index 33a0a1d0..a872aeeb 100644 --- a/codegen/src/decorators/mod.rs +++ b/codegen/src/decorators/mod.rs @@ -1,8 +1,8 @@ mod route; -mod error; +mod catch; mod derive_form; pub use self::route::*; -pub use self::error::*; +pub use self::catch::*; pub use self::derive_form::*; diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index 9d18a91b..a10b0847 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -17,7 +17,7 @@ //! * **head** //! * **patch** //! * **options** -//! * **error** +//! * **catch** //! //! The grammar for all _route_ attributes, including **route**, **get**, //! **put**, **post**, **delete**, **head**, **patch**, and **options** is @@ -53,15 +53,15 @@ //! //! #[get("/hello")] //! -//! The syntax for the **error** attribute is: +//! The syntax for the **catch** attribute is: //! //!
-//! error := INTEGER
+//! catch := INTEGER
 //! 
//! -//! A use of the `error` attribute looks like: +//! A use of the `catch` attribute looks like: //! -//! #[error(404)] +//! #[catch(404)] //! //! ## Custom Derives //! @@ -115,10 +115,10 @@ //! This crate implements the following procedural macros: //! //! * **routes** -//! * **errors** +//! * **catchers** //! * **uri** //! -//! The syntax for `routes!` and `errors!` is defined as: +//! The syntax for `routes!` and `catchers!` is defined as: //! //!
 //! macro := PATH (',' PATH)*
@@ -283,7 +283,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
 
     register_macros!(reg,
         "routes" => routes,
-        "errors" => errors,
+        "catchers" => catchers,
         "uri" => uri,
         "rocket_internal_uri" => uri_internal
     );
@@ -293,7 +293,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
     );
 
     register_decorators!(reg,
-        "error" => error_decorator,
+        "catch" => catch_decorator,
         "route" => route_decorator,
         "get" => get_decorator,
         "put" => put_decorator,
diff --git a/codegen/src/macros/mod.rs b/codegen/src/macros/mod.rs
index 59426ab7..ce34ce2e 100644
--- a/codegen/src/macros/mod.rs
+++ b/codegen/src/macros/mod.rs
@@ -64,7 +64,7 @@ pub fn routes(ecx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
 }
 
 #[rustfmt_skip]
-pub fn errors(ecx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
+pub fn catchers(ecx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         -> Box {
     prefixing_vec_macro(CATCH_STRUCT_PREFIX, |ecx, path| {
         quote_expr!(ecx, rocket::Catcher::from(&$path))
diff --git a/codegen/src/parser/error.rs b/codegen/src/parser/catch.rs
similarity index 90%
rename from codegen/src/parser/error.rs
rename to codegen/src/parser/catch.rs
index f9cd651d..d1d57c41 100644
--- a/codegen/src/parser/error.rs
+++ b/codegen/src/parser/catch.rs
@@ -7,13 +7,13 @@ use rocket::http::Status;
 use utils::{span, MetaItemExt};
 use super::Function;
 
-/// This structure represents the parsed `error` attribute.
-pub struct ErrorParams {
+/// This structure represents the parsed `catch` attribute.
+pub struct CatchParams {
     pub annotated_fn: Function,
     pub code: Spanned,
 }
 
-impl ErrorParams {
+impl CatchParams {
     /// Parses the route attribute from the given decorator context. If the
     /// parse is not successful, this function exits early with the appropriate
     /// error message to the user.
@@ -21,7 +21,7 @@ impl ErrorParams {
                 sp: Span,
                 meta_item: &MetaItem,
                 annotated: &Annotatable)
-                -> ErrorParams {
+                -> CatchParams {
         let function = Function::from(annotated).unwrap_or_else(|item_sp| {
             ecx.span_err(sp, "this attribute can only be used on functions...");
             ecx.span_fatal(item_sp, "...but was applied to the item above.");
@@ -40,7 +40,7 @@ impl ErrorParams {
             ecx.span_fatal(sp, "attribute can only have one `code` parameter");
         }
 
-        ErrorParams {
+        CatchParams {
             annotated_fn: function,
             code: parse_code(ecx, &meta_items[0])
         }
@@ -74,8 +74,8 @@ fn parse_code(ecx: &ExtCtxt, meta_item: &NestedMetaItem) -> Spanned {
     } else {
         ecx.struct_span_err(sp, r#"expected `code = int` or an integer literal"#)
             .help(r#"you can specify the code directly as an integer,
-                  e.g: #[error(404)], or as a key-value pair,
-                  e.g: $[error(code = 404)]"#)
+                  e.g: #[catch(404)], or as a key-value pair,
+                  e.g: $[catch(code = 404)]"#)
             .emit();
     }
 
diff --git a/codegen/src/parser/mod.rs b/codegen/src/parser/mod.rs
index bdab9f0c..07bc00c5 100644
--- a/codegen/src/parser/mod.rs
+++ b/codegen/src/parser/mod.rs
@@ -1,6 +1,6 @@
 mod keyvalue;
 mod route;
-mod error;
+mod catch;
 mod param;
 mod function;
 mod uri;
@@ -8,7 +8,7 @@ mod uri_macro;
 
 pub use self::keyvalue::KVSpanned;
 pub use self::route::RouteParams;
-pub use self::error::ErrorParams;
+pub use self::catch::CatchParams;
 pub use self::param::Param;
 pub use self::function::Function;
 pub use self::uri_macro::{Args, InternalUriParams, UriParams, Validation};
diff --git a/codegen/tests/error-handler.rs b/codegen/tests/error-handler.rs
index 8e374058..306c7a7b 100644
--- a/codegen/tests/error-handler.rs
+++ b/codegen/tests/error-handler.rs
@@ -5,19 +5,19 @@ extern crate rocket;
 
 use rocket::{Error, Request};
 
-#[error(404)]
+#[catch(404)]
 fn err0() -> &'static str { "hi" }
 
-#[error(404)]
+#[catch(404)]
 fn err1a(_err: Error) -> &'static str { "hi" }
 
-#[error(404)]
+#[catch(404)]
 fn err1b(_req: &Request) -> &'static str { "hi" }
 
-#[error(404)]
+#[catch(404)]
 fn err2a(_err: Error, _req: &Request) -> &'static str { "hi" }
 
-#[error(404)]
+#[catch(404)]
 fn err2b<'a>(_err: Error, _req: &'a Request) -> &'a str { "hi" }
 
 #[test]
diff --git a/codegen/tests/compile-fail/bad-error-fn.rs b/codegen/tests/ui/bad-error-fn.rs
similarity index 66%
rename from codegen/tests/compile-fail/bad-error-fn.rs
rename to codegen/tests/ui/bad-error-fn.rs
index 7ef8525d..0d395d32 100644
--- a/codegen/tests/compile-fail/bad-error-fn.rs
+++ b/codegen/tests/ui/bad-error-fn.rs
@@ -5,14 +5,8 @@ extern crate rocket;
 
 use rocket::{Error, Request};
 
-#[error(404)]
+#[catch(404)]
 fn err_a(_a: Error, _b: Request, _c: Error) -> &'static str { "hi" }
-//~^ ERROR: can have at most 2
 
-#[error(404)]
+#[catch(404)]
 fn err_b(_a: (isize, usize)) -> &'static str { "hi" }
-//~^ ERROR: unexpected error handler argument
-
-fn main() {
-}
-
diff --git a/codegen/tests/ui/bad-error-fn.stderr b/codegen/tests/ui/bad-error-fn.stderr
new file mode 100644
index 00000000..5d337418
--- /dev/null
+++ b/codegen/tests/ui/bad-error-fn.stderr
@@ -0,0 +1,18 @@
+error: error catchers can have at most 2 arguments
+ --> $DIR/bad-error-fn.rs:9:1
+  |
+9 | fn err_a(_a: Error, _b: Request, _c: Error) -> &'static str { "hi" }
+  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+  |
+  = help: error catchers can take either a `rocket::Error`, `rocket::Request` type, or both.
+
+error: unknown error catcher argument
+  --> $DIR/bad-error-fn.rs:12:14
+   |
+12 | fn err_b(_a: (isize, usize)) -> &'static str { "hi" }
+   |              ^^^^^^^^^^^^^^
+   |
+   = help: error catchers can take either a `rocket::Error`, `rocket::Request` type, or both.
+
+error: aborting due to 2 previous errors
+
diff --git a/examples/content_types/src/main.rs b/examples/content_types/src/main.rs
index 0ba79db3..020f19b4 100644
--- a/examples/content_types/src/main.rs
+++ b/examples/content_types/src/main.rs
@@ -35,7 +35,7 @@ fn post_hello(age: u8, name: String) -> content::Json {
     content::Json(serde_json::to_string(&person).unwrap())
 }
 
-#[error(404)]
+#[catch(404)]
 fn not_found(request: &Request) -> content::Html {
     let html = match request.format() {
         Some(ref mt) if !mt.is_json() && !mt.is_plain() => {
@@ -52,6 +52,6 @@ fn not_found(request: &Request) -> content::Html {
 fn main() {
     rocket::ignite()
         .mount("/hello", routes![get_hello, post_hello])
-        .catch(errors![not_found])
+        .catch(catchers![not_found])
         .launch();
 }
diff --git a/examples/content_types/src/tests.rs b/examples/content_types/src/tests.rs
index 15f7fa89..9d655841 100644
--- a/examples/content_types/src/tests.rs
+++ b/examples/content_types/src/tests.rs
@@ -9,7 +9,7 @@ fn test(method: Method, uri: &str, header: H, status: Status, body: String)
 {
     let rocket = rocket::ignite()
         .mount("/hello", routes![super::get_hello, super::post_hello])
-        .catch(errors![super::not_found]);
+        .catch(catchers![super::not_found]);
 
     let client = Client::new(rocket).unwrap();
     let mut response = client.req(method, uri).header(header).dispatch();
diff --git a/examples/errors/src/main.rs b/examples/errors/src/main.rs
index 07210db8..cf56e18a 100644
--- a/examples/errors/src/main.rs
+++ b/examples/errors/src/main.rs
@@ -12,7 +12,7 @@ fn hello(name: String, age: i8) -> String {
     format!("Hello, {} year old named {}!", age, name)
 }
 
-#[error(404)]
+#[catch(404)]
 fn not_found(req: &rocket::Request) -> content::Html {
     content::Html(format!("

Sorry, but '{}' is not a valid path!

Try visiting /hello/<name>/<age> instead.

", @@ -23,7 +23,7 @@ fn main() { let e = rocket::ignite() // .mount("/", routes![hello, hello]) // uncoment this to get an error .mount("/", routes![hello]) - .catch(errors![not_found]) + .catch(catchers![not_found]) .launch(); println!("Whoops! Rocket didn't launch!"); diff --git a/examples/errors/src/tests.rs b/examples/errors/src/tests.rs index fc0b5523..01bc7100 100644 --- a/examples/errors/src/tests.rs +++ b/examples/errors/src/tests.rs @@ -5,7 +5,7 @@ use rocket::http::Status; fn test(uri: &str, status: Status, body: String) { let rocket = rocket::ignite() .mount("/", routes![super::hello]) - .catch(errors![super::not_found]); + .catch(catchers![super::not_found]); let client = Client::new(rocket).unwrap(); let mut response = client.get(uri).dispatch(); diff --git a/examples/handlebars_templates/src/main.rs b/examples/handlebars_templates/src/main.rs index a1f1b77c..330353c9 100644 --- a/examples/handlebars_templates/src/main.rs +++ b/examples/handlebars_templates/src/main.rs @@ -32,7 +32,7 @@ fn get(name: String) -> Template { Template::render("index", &context) } -#[error(404)] +#[catch(404)] fn not_found(req: &Request) -> Template { let mut map = std::collections::HashMap::new(); map.insert("path", req.uri().as_str()); @@ -43,7 +43,7 @@ fn rocket() -> rocket::Rocket { rocket::ignite() .mount("/", routes![index, get]) .attach(Template::fairing()) - .catch(errors![not_found]) + .catch(catchers![not_found]) } fn main() { diff --git a/examples/json/src/main.rs b/examples/json/src/main.rs index d0352e86..4ec7e1b3 100644 --- a/examples/json/src/main.rs +++ b/examples/json/src/main.rs @@ -61,7 +61,7 @@ fn get(id: ID, map: State) -> Option> { }) } -#[error(404)] +#[catch(404)] fn not_found() -> JsonValue { json!({ "status": "error", @@ -72,7 +72,7 @@ fn not_found() -> JsonValue { fn rocket() -> rocket::Rocket { rocket::ignite() .mount("/message", routes![new, update, get]) - .catch(errors![not_found]) + .catch(catchers![not_found]) .manage(Mutex::new(HashMap::::new())) } diff --git a/examples/todo/static/css/normalize.css b/examples/todo/static/css/normalize.css index 81c6f31e..458eea1e 100644 --- a/examples/todo/static/css/normalize.css +++ b/examples/todo/static/css/normalize.css @@ -424,4 +424,4 @@ table { td, th { padding: 0; -} \ No newline at end of file +} diff --git a/lib/src/catcher.rs b/lib/src/catcher.rs index e7d71d00..aaeadd3c 100644 --- a/lib/src/catcher.rs +++ b/lib/src/catcher.rs @@ -32,7 +32,7 @@ use yansi::Color::*; /// # Code Generation /// /// Catchers should rarely be used directly. Instead, they are typically -/// declared using the `error` decorator, as follows: +/// declared using the `catch` decorator, as follows: /// /// ```rust /// #![feature(plugin, decl_macro)] @@ -42,24 +42,24 @@ use yansi::Color::*; /// /// use rocket::Request; /// -/// #[error(500)] +/// #[catch(500)] /// fn internal_error() -> &'static str { /// "Whoops! Looks like we messed up." /// } /// -/// #[error(400)] +/// #[catch(400)] /// fn not_found(req: &Request) -> String { /// format!("I couldn't find '{}'. Try something else?", req.uri()) /// } /// /// fn main() { /// # if false { // We don't actually want to launch the server in an example. -/// rocket::ignite().catch(errors![internal_error, not_found]).launch(); +/// rocket::ignite().catch(catchers![internal_error, not_found]).launch(); /// # } /// } /// ``` /// -/// A function decorated with `error` can take in 0, 1, or 2 parameters: +/// A function decorated with `catch` can take in 0, 1, or 2 parameters: /// `Error`, `&Request`, or both, as desired. pub struct Catcher { /// The HTTP status code to match against. @@ -150,7 +150,7 @@ macro_rules! error_page_template { ) } -macro_rules! default_errors { +macro_rules! default_catchers { ($($code:expr, $name:expr, $description:expr, $fn_name:ident),+) => ( let mut map = HashMap::new(); @@ -179,7 +179,7 @@ pub mod defaults { use error::Error; pub fn get() -> HashMap { - default_errors! { + default_catchers! { 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.", diff --git a/lib/src/rocket.rs b/lib/src/rocket.rs index 1af7230d..52f276a3 100644 --- a/lib/src/rocket.rs +++ b/lib/src/rocket.rs @@ -521,19 +521,19 @@ impl Rocket { /// /// use rocket::Request; /// - /// #[error(500)] + /// #[catch(500)] /// fn internal_error() -> &'static str { /// "Whoops! Looks like we messed up." /// } /// - /// #[error(400)] + /// #[catch(400)] /// fn not_found(req: &Request) -> String { /// format!("I couldn't find '{}'. Try something else?", req.uri()) /// } /// /// fn main() { /// # if false { // We don't actually want to launch the server in an example. - /// rocket::ignite().catch(errors![internal_error, not_found]) + /// rocket::ignite().catch(catchers![internal_error, not_found]) /// # .launch(); /// # } /// } diff --git a/lib/tests/redirect_from_catcher-issue-113.rs b/lib/tests/redirect_from_catcher-issue-113.rs index 2b6f71b5..b5cf712f 100644 --- a/lib/tests/redirect_from_catcher-issue-113.rs +++ b/lib/tests/redirect_from_catcher-issue-113.rs @@ -5,7 +5,7 @@ extern crate rocket; use rocket::response::Redirect; -#[error(404)] +#[catch(404)] fn not_found() -> Redirect { Redirect::to("/") } @@ -17,7 +17,7 @@ mod tests { #[test] fn error_catcher_redirect() { - let client = Client::new(rocket::ignite().catch(errors![not_found])).unwrap(); + let client = Client::new(rocket::ignite().catch(catchers![not_found])).unwrap(); let response = client.get("/unknown").dispatch(); println!("Response:\n{:?}", response); diff --git a/site/guide/requests.md b/site/guide/requests.md index c1535400..16b7de18 100644 --- a/site/guide/requests.md +++ b/site/guide/requests.md @@ -737,22 +737,22 @@ Routing may fail for a variety of reasons. These include: If any of these conditions occur, Rocket returns an error to the client. To do so, Rocket invokes the _error catcher_ corresponding to the error's status code. A catcher is like a route, except it only handles errors. Catchers are declared -via the `error` attribute, which takes a single integer corresponding to the +via the `catch` attribute, which takes a single integer corresponding to the HTTP status code to catch. For instance, to declare a catcher for **404** errors, you'd write: ```rust -#[error(404)] +#[catch(404)] fn not_found(req: &Request) -> String { ... } ``` As with routes, Rocket needs to know about a catcher before it is used to handle errors. The process is similar to mounting: call the `catch` method with a list -of catchers via the `errors!` macro. The invocation to add the **404** catcher +of catchers via the `catchers!` macro. The invocation to add the **404** catcher declared above looks like: ```rust -rocket::ignite().catch(errors![not_found]) +rocket::ignite().catch(catchers![not_found]) ``` Unlike request handlers, error handlers can only take 0, 1, or 2 parameters of diff --git a/site/overview.toml b/site/overview.toml index 554b710d..e4d7ba0a 100644 --- a/site/overview.toml +++ b/site/overview.toml @@ -124,12 +124,13 @@ the standard library types including `&str`, `String`, `File`, `Option`, and [Template](https://api.rocket.rs/rocket_contrib/struct.Template.html). The task of a `Responder` is to generate a -[Response](https://api.rocket.rs/rocket/response/struct.Response.html), if +[`Response`](https://api.rocket.rs/rocket/response/struct.Response.html), if possible. `Responder`s can fail with a status code. When they do, Rocket calls -the corresponding `error` route, which can be declared as follows: +the corresponding error catcher, a `catch` route, which can be declared as +follows: ```rust -#[error(404)] +#[catch(404)] fn not_found() -> T { ... } ``` '''