Skip to content

Commit

Permalink
(doc) Added AfterMiddleware to error_recovery example
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul Dib committed Oct 6, 2015
1 parent 943bc4c commit f1ef5f5
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 8 deletions.
48 changes: 40 additions & 8 deletions examples/error_recovery.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
// This example illustrates the error flow of a Request in BeforeMiddleware.
// This example illustrates the error flow of a Request in the middleware Chain.
// Here is the chain used and the path of the request through the middleware pieces:
//
// Normal Flow : ____[ErrorProducer::before]_____ [ErrorRecover::before] ____[HelloWorldHandler::handle]___
// Error Flow : [ErrorProducer::catch ] |____[ErrorRecover::catch ]_____|

// Normal Flow : __[ErrorProducer::before]__ [ErrorRecover::before] __[handle::HelloWorldHandler]__[ErrorProducer::after]__ [ErrorRecover::after] __ ...
// Error Flow : [ErrorProducer::catch ] |__[ErrorRecover::catch ]__| [ErrorProducer::catch] |__[ErrorRecover::catch]__|
//
// --------------- BEFORE MIDDLEWARE ----------------- || --------- HANDLER -------- || ---------------- AFTER MIDDLEWARE --------------

extern crate iron;

use iron::prelude::*;
use iron::status;
use iron::{Handler, BeforeMiddleware};
use iron::{Handler, BeforeMiddleware, AfterMiddleware};

use std::error::Error;
use std::fmt::{self, Debug};
Expand All @@ -33,6 +34,9 @@ impl Error for StringError {

impl Handler for HelloWorldHandler {
fn handle(&self, _: &mut Request) -> IronResult<Response> {
// This will be called since we are in the normal flow before reaching the Handler.
// However, the AfterMiddleware chain will override the Response.
println!("The HelloWorldHandler has been called !");
Ok(Response::with((status::Ok, "Hello world !")))
}
}
Expand All @@ -42,26 +46,54 @@ impl BeforeMiddleware for ErrorProducer {
// The error produced here switches to the error flow.
// The catch method of following middleware pieces will be called.
// The Handler will be skipped unless the error is handled by another middleware piece.
Err(IronError::new(StringError("Error in ErrorProducer".to_string()), status::BadRequest))
// IronError::error tells the next middleware what went wrong.
// IronError::response is the Response that will be sent back to the client if this error is not handled.
// Here status::BadRequest acts as modifier, thus we can put more there than just a status.
Err(IronError::new(StringError("Error in ErrorProducer BeforeMiddleware".to_string()), status::BadRequest))
}
}

impl AfterMiddleware for ErrorProducer {
fn after(&self, _: &mut Request, _: Response) -> IronResult<Response> {
// The behavior here is the same as in ErrorProducer::before.
// The previous response (from the Handler) is discarded and replaced with a new response (created from the modifier).
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<()> {
// We can use the IronError from previous middleware to decide what to do.
// Returning Ok() from a catch method resumes the normal flow.
println!("{} caught in ErrorRecover.", err.error);
// Returning Ok() from a catch method resumes the normal flow and
// passes the Request forward to the next middleware piece in the chain (here the HelloWorldHandler).
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> {
// Just like in the BeforeMiddleware, we can return Ok(Response) here to return to the normal flow.
// In this case, ErrorRecover is the last middleware in the chain
// and the Response created in the ErrorProducer is modified and sent back to the client.
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();
}
4 changes: 4 additions & 0 deletions examples/simple_routing.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// This example shows how to create a basic router that maps url to different handlers.
// If you're looking for real routing middleware, check https://github.com/iron/router

extern crate iron;

use std::collections::HashMap;
Expand Down Expand Up @@ -32,6 +35,7 @@ impl Handler for Router {

fn main() {
let mut router = Router::new();

router.add_route("hello".to_string(), |_: &mut Request| {
Ok(Response::with("Hello world !"))
});
Expand Down

0 comments on commit f1ef5f5

Please sign in to comment.