pub trait Handler:
Cloneable
+ Send
+ Sync
+ 'static {
// Required method
fn handle<'r, 'life0, 'life1, 'async_trait>(
&'life0 self,
status: Status,
req: &'r Request<'life1>,
) -> Pin<Box<dyn Future<Output = Result<'r>> + Send + 'async_trait>>
where Self: 'async_trait,
'r: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
}
Expand description
Trait implemented by Catcher
error handlers.
This trait is exactly like a Route
’s
Handler
except it handles errors instead of
requests. Thus, the documentation for
route::Handler
applies to this trait as well. We
defer to it for full details.
§Async Trait
This is an async trait. Implementations must be decorated
#[rocket::async_trait]
.
§Example
Say you’d like to write a handler that changes its functionality based on a
Kind
enum value that the user provides. Such a handler might be written
and used as follows:
use rocket::{Request, Catcher, catcher};
use rocket::response::{Response, Responder};
use rocket::http::Status;
#[derive(Copy, Clone)]
enum Kind {
Simple,
Intermediate,
Complex,
}
#[derive(Clone)]
struct CustomHandler(Kind);
#[rocket::async_trait]
impl catcher::Handler for CustomHandler {
async fn handle<'r>(&self, status: Status, req: &'r Request<'_>) -> catcher::Result<'r> {
let inner = match self.0 {
Kind::Simple => "simple".respond_to(req)?,
Kind::Intermediate => "intermediate".respond_to(req)?,
Kind::Complex => "complex".respond_to(req)?,
};
Response::build_from(inner).status(status).ok()
}
}
impl CustomHandler {
/// Returns a `default` catcher that uses `CustomHandler`.
fn default(kind: Kind) -> Vec<Catcher> {
vec![Catcher::new(None, CustomHandler(kind))]
}
/// Returns a catcher for code `status` that uses `CustomHandler`.
fn catch(status: Status, kind: Kind) -> Vec<Catcher> {
vec![Catcher::new(status.code, CustomHandler(kind))]
}
}
#[rocket::launch]
fn rocket() -> _ {
rocket::build()
// to handle only `404`
.register("/", CustomHandler::catch(Status::NotFound, Kind::Simple))
// or to register as the default
.register("/", CustomHandler::default(Kind::Simple))
}
Note the following:
CustomHandler
implementsClone
. This is required so thatCustomHandler
implementsCloneable
automatically. TheCloneable
trait serves no other purpose but to ensure that everyHandler
can be cloned, allowingCatcher
s to be cloned.CustomHandler
’s methods returnVec<Route>
, allowing for use directly as the parameter torocket.register("/", )
.- Unlike static-function-based handlers, this custom handler can make use of internal state.
Required Methods§
Sourcefn handle<'r, 'life0, 'life1, 'async_trait>(
&'life0 self,
status: Status,
req: &'r Request<'life1>,
) -> Pin<Box<dyn Future<Output = Result<'r>> + Send + 'async_trait>>where
Self: 'async_trait,
'r: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn handle<'r, 'life0, 'life1, 'async_trait>(
&'life0 self,
status: Status,
req: &'r Request<'life1>,
) -> Pin<Box<dyn Future<Output = Result<'r>> + Send + 'async_trait>>where
Self: 'async_trait,
'r: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Called by Rocket when an error with status
for a given Request
should be handled by this handler.
Error handlers should not fail and thus should always return Ok
.
Nevertheless, failure is allowed, both for convenience and necessity. If
an error handler fails, Rocket’s default 500
catcher is invoked. If it
succeeds, the returned Response
is used to respond to the client.