iron / router

Router middleware for the Iron web framework.
165 stars 74 forks source link

How am I supposed to handle the `NoRoute` error? #100

Closed lilydjwg closed 8 years ago

lilydjwg commented 8 years ago

I want to write a middleware that provides custom error pages for the NoRoute error, but I didn't figure out how to know whether an IronError is caused by NoRoute.

This is what I've got:

impl AfterMiddleware for MyErrorHandler {
    fn catch(&self, req: &mut Request, err: IronError) -> IronResult<Response> {
        if /* ??? err.error is NoRoute */ {
            // custom handling happens
        } else {
            Ok(err.response)
        }
    }
}
alilleybrinker commented 8 years ago

You should be able to pattern match on the error field of IronError. As you can see in router.rs, NoRoute is placed into the error field via IronError::new(). Note though that this means NoRoute will be Boxed, which will need to be included in the pattern.

reem commented 8 years ago

You'll have to use the downcast or is methods, available via the Error trait.

lilydjwg commented 8 years ago

@reem how should I use it? I tried but got the following error:

src/basic.rs:33:21: 33:36 error: no method named `is` found for type `error::Error + Send + 'static` in the current scope
src/basic.rs:33     if (*err.error).is::<NoRoute>() {
                                    ^~~~~~~~~~~~~~~
kellenfujimoto commented 8 years ago

@lilydjwg have you checked out the custom_404.rs example file?

impl AfterMiddleware for Custom404 {
    fn catch(&self, _: &mut Request, err: IronError) -> IronResult<Response> {
        println!("Hitting custom 404 middleware");

        if let Some(_) = err.error.downcast::<NoRoute>() {
            Ok(Response::with((status::NotFound, "Custom 404 response")))
        } else {
            Err(err)
        }
    }
}
lilydjwg commented 8 years ago

@kellenfujimoto thanks, it works!