extern crate iron;
use iron::prelude::*;
use iron::status;
use iron::{Handler, BeforeMiddleware, AfterMiddleware};
use std::error::Error;
use std::fmt::{self, Debug};
struct HelloWorldHandler;
struct ErrorProducer;
struct ErrorRecover;
#[derive(Debug)]
struct StringError(String);
impl fmt::Display for StringError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(self, f)
}
}
impl Error for StringError {
fn description(&self) -> &str { &*self.0 }
}
impl Handler for HelloWorldHandler {
fn handle(&self, _: &mut Request) -> IronResult<Response> {
println!("The HelloWorldHandler has been called !");
Ok(Response::with((status::Ok, "Hello world !")))
}
}
impl BeforeMiddleware for ErrorProducer {
fn before(&self, _: &mut Request) -> IronResult<()> {
Err(IronError::new(StringError("Error in ErrorProducer BeforeMiddleware".to_string()), status::BadRequest))
}
}
impl AfterMiddleware for ErrorProducer {
fn after(&self, _: &mut Request, _: Response) -> IronResult<Response> {
Err(IronError::new(StringError("Error in ErrorProducer AfterMiddleware".to_string()), (status::BadRequest, "Response created in ErrorProducer")))
}
}
impl BeforeMiddleware for ErrorRecover {
fn catch(&self, _: &mut Request, err: IronError) -> IronResult<()> {
println!("{} caught in ErrorRecover BeforeMiddleware.", err.error);
match err.response.status {
Some(status::BadRequest) => Ok(()),
_ => Err(err)
}
}
}
impl AfterMiddleware for ErrorRecover {
fn catch(&self, _: &mut Request, err: IronError) -> IronResult<Response> {
println!("{} caught in ErrorRecover AfterMiddleware.", err.error);
match err.response.status {
Some(status::BadRequest) => Ok(err.response.set(status::Ok)),
_ => Err(err)
}
}
}
fn main() {
let mut chain = Chain::new(HelloWorldHandler);
chain.link_before(ErrorProducer);
chain.link_before(ErrorRecover);
chain.link_after(ErrorProducer);
chain.link_after(ErrorRecover);
Iron::new(chain).http("localhost:3000").unwrap();
}