mirror of https://github.com/rwf2/Rocket.git
parent
63d31e8082
commit
d4f9525b22
|
@ -2,10 +2,50 @@ use utils::*;
|
||||||
use ::{CATCH_STRUCT_PREFIX, CATCH_FN_PREFIX};
|
use ::{CATCH_STRUCT_PREFIX, CATCH_FN_PREFIX};
|
||||||
|
|
||||||
use syntax::codemap::{Span};
|
use syntax::codemap::{Span};
|
||||||
use syntax::ast::{MetaItem};
|
use syntax::ast::{MetaItem, Ident, TyKind};
|
||||||
use syntax::ext::base::{Annotatable, ExtCtxt};
|
use syntax::ext::base::{Annotatable, ExtCtxt};
|
||||||
|
use syntax::tokenstream::TokenTree;
|
||||||
|
use syntax::parse::token::{self, str_to_ident};
|
||||||
use parser::ErrorParams;
|
use parser::ErrorParams;
|
||||||
|
|
||||||
|
const ERR_PARAM: &'static str = "_error";
|
||||||
|
const REQ_PARAM: &'static str = "_request";
|
||||||
|
|
||||||
|
trait ErrorGenerateExt {
|
||||||
|
fn generate_fn_arguments(&self, &ExtCtxt, Ident, Ident) -> Vec<TokenTree>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ErrorGenerateExt for ErrorParams {
|
||||||
|
fn generate_fn_arguments(&self, ecx: &ExtCtxt, err: Ident, req: Ident)
|
||||||
|
-> Vec<TokenTree> {
|
||||||
|
let arg_help = "error handlers can take either a `rocket::Error` or \
|
||||||
|
`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")
|
||||||
|
.help(arg_help).emit()
|
||||||
|
}
|
||||||
|
|
||||||
|
// (Imperfectly) inspect the types to figure which params to pass in.
|
||||||
|
let args = input_args.iter().map(|arg| &arg.ty).filter_map(|ty| {
|
||||||
|
match ty.node {
|
||||||
|
TyKind::Rptr(..) => Some(req.clone()),
|
||||||
|
TyKind::Path(..) => Some(err.clone()),
|
||||||
|
_ => {
|
||||||
|
ecx.struct_span_err(ty.span, "unexpected error handler argument")
|
||||||
|
.help(arg_help).emit();
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
sep_by_tok(ecx, &args, token::Comma)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn error_decorator(ecx: &mut ExtCtxt, sp: Span, meta_item: &MetaItem,
|
pub fn error_decorator(ecx: &mut ExtCtxt, sp: Span, meta_item: &MetaItem,
|
||||||
annotated: &Annotatable, push: &mut FnMut(Annotatable)) {
|
annotated: &Annotatable, push: &mut FnMut(Annotatable)) {
|
||||||
let error = ErrorParams::from(ecx, sp, meta_item, annotated);
|
let error = ErrorParams::from(ecx, sp, meta_item, annotated);
|
||||||
|
@ -13,11 +53,14 @@ pub fn error_decorator(ecx: &mut ExtCtxt, sp: Span, meta_item: &MetaItem,
|
||||||
let user_fn_name = error.annotated_fn.ident();
|
let user_fn_name = error.annotated_fn.ident();
|
||||||
let catch_fn_name = user_fn_name.prepend(CATCH_FN_PREFIX);
|
let catch_fn_name = user_fn_name.prepend(CATCH_FN_PREFIX);
|
||||||
let code = error.code.node;
|
let code = error.code.node;
|
||||||
|
let (err_ident, req_ident) = (str_to_ident(ERR_PARAM), str_to_ident(REQ_PARAM));
|
||||||
|
let fn_arguments = error.generate_fn_arguments(ecx, err_ident, req_ident);
|
||||||
|
|
||||||
emit_item(push, quote_item!(ecx,
|
emit_item(push, quote_item!(ecx,
|
||||||
fn $catch_fn_name<'rocket>(err: ::rocket::Error,
|
fn $catch_fn_name<'rocket>($err_ident: ::rocket::Error,
|
||||||
req: &'rocket ::rocket::Request<'rocket>)
|
$req_ident: &'rocket ::rocket::Request<'rocket>)
|
||||||
-> ::rocket::Response<'rocket> {
|
-> ::rocket::Response<'rocket> {
|
||||||
let result = $user_fn_name(err, req);
|
let result = $user_fn_name($fn_arguments);
|
||||||
rocket::Response::with_raw_status($code, result)
|
rocket::Response::with_raw_status($code, result)
|
||||||
}
|
}
|
||||||
).expect("catch function"));
|
).expect("catch function"));
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
#![feature(plugin)]
|
||||||
|
#![plugin(rocket_codegen)]
|
||||||
|
|
||||||
|
extern crate rocket;
|
||||||
|
|
||||||
|
use rocket::{Error, Request};
|
||||||
|
|
||||||
|
#[error(404)]
|
||||||
|
fn err_a(_a: Error, _b: Request, _c: Error) -> &'static str { "hi" }
|
||||||
|
//~^ ERROR: can have at most 2
|
||||||
|
|
||||||
|
#[error(404)]
|
||||||
|
fn err_b(_a: (isize, usize)) -> &'static str { "hi" }
|
||||||
|
//~^ ERROR: unexpected error handler argument
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
#![feature(plugin)]
|
||||||
|
#![plugin(rocket_codegen)]
|
||||||
|
|
||||||
|
extern crate rocket;
|
||||||
|
|
||||||
|
use rocket::{Error, Request};
|
||||||
|
|
||||||
|
#[error(404)]
|
||||||
|
fn err0() -> &'static str { "hi" }
|
||||||
|
|
||||||
|
#[error(404)]
|
||||||
|
fn err1a(_err: Error) -> &'static str { "hi" }
|
||||||
|
|
||||||
|
#[error(404)]
|
||||||
|
fn err1b(_req: &Request) -> &'static str { "hi" }
|
||||||
|
|
||||||
|
#[error(404)]
|
||||||
|
fn err2(_err: Error, _req: &Request) -> &'static str { "hi" }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
rocket::ignite()
|
||||||
|
.catch(errors![err0, err1a, err1b, err2]);
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#![plugin(rocket_codegen)]
|
#![plugin(rocket_codegen)]
|
||||||
|
|
||||||
extern crate rocket;
|
extern crate rocket;
|
||||||
use rocket::{Error, Request};
|
|
||||||
|
|
||||||
#[get("/hello/<name>/<age>")]
|
#[get("/hello/<name>/<age>")]
|
||||||
fn hello(name: &str, age: i8) -> String {
|
fn hello(name: &str, age: i8) -> String {
|
||||||
|
@ -10,10 +9,10 @@ fn hello(name: &str, age: i8) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[error(404)]
|
#[error(404)]
|
||||||
fn not_found<'r>(_error: Error, request: &'r Request<'r>) -> String {
|
fn not_found(req: &rocket::Request) -> String {
|
||||||
format!("<p>Sorry, but '{}' is not a valid path!</p>
|
format!("<p>Sorry, but '{}' is not a valid path!</p>
|
||||||
<p>Try visiting /hello/<name>/<age> instead.</p>",
|
<p>Try visiting /hello/<name>/<age> instead.</p>",
|
||||||
request.uri)
|
req.uri)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
BadMethod,
|
BadMethod,
|
||||||
BadParse,
|
BadParse,
|
||||||
NoRoute, // FIXME: Add a chain of routes attempted.
|
NoRoute, // TODO: Add a chain of routes attempted.
|
||||||
Internal,
|
Internal,
|
||||||
NoKey,
|
NoKey,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue