Allow catcher to access rucket::state
Is your feature request motivated by a concrete problem? Please describe.
When i'm implement #[catch(default)] function to catch any error in the API, i can't access to rocket::State.
Adding state: &State<StateContext> to the catch function getting the attached error:
catchers optionally take `&Request` or `Status, &Request`
Is your feature request motivated by a concrete problem? Please describe. Example:
#[macro_use] extern crate rocket;
use rocket::request::Request;
use rocket::State;
use rocket::http::Status;
struct StateContext {
foo: String
}
#[get("/info")]
fn info(state: &State<StateContext>) -> &'static str {
println!("state foo value: {}", state.foo);
"Hello, world!"
}
#[catch(default)]
fn default(status: Status, req: &Request, state: &State<StateContext>) -> String {
println!("state foo value: {}", state.foo);
format!("Sorry, '{}' is not a valid path.", req.uri())
}
#[launch]
fn rocket() -> _ {
let config = StateContext {
foo: "bar".to_string()
};
rocket::build()
.manage(config)
.mount("/", routes![info])
.register("/", catchers![default])
}
Why this feature can't or shouldn't live outside of Rocket
The state should be a part of the Rucket interface
Ideal Solution
Function that using #[catch(default)] or #[catch(404)] can get rucket state
Rocket doesn't let you put guard arguments on error catchers because that would make them faillible/forwardable too... but they're supposed to catch all errors.
However, if you look at the Request type, you'll see that it has a Request::guard method that you can use to retrieve your state. This is the method that's used when rocket expands the #[get] macro-attribute on your usual handlers ; it will work the same way.
#[catch(default)]
fn default(status: Status, req: &Request) -> String {
// Notice the `unwrap` here. If you're sure that the state will be defined, you can keep it
// but remember that panicking is not a proper way to handle errors in Rust.
let state = req.guard::<State<StateContext>>().unwrap();
println!("state foo value: {}", state.foo);
format!("Sorry, '{}' is not a valid path.", req.uri())
}
Sound good! thanks @edgarogh