#[status_code]Expand description
A macro to attach status codes to enum errors.
use http::StatusCode;
#[status_code]
pub enum DatabaseError {
#[code(StatusCode::NOT_FOUND)]
NotFoundInDatabase,
#[code(StatusCode::INTERNAL_SERVER_ERROR)]
DatabaseNetworkError
}You can also set a default and override when neccesary.
use http::StatusCode;
#[status_code(StatusCode::FORBIDDEN)]
pub enum TokenError {
MalformedToken,
InvalidToken,
#[code(StatusCode::INTERNAL_SERVER_ERROR)]
DeserializationError
}You can even include the contents of the enum!
use http::StatusCode;
#[status_code]
pub enum Error {
#[pattern((code, _, _))]
// Note that you have to deference as we borrow the enum
#[code(*code)]
Dynamic(StatusCode, (), ()),
#[pattern({ status, .. })]
#[code(*status)]
DynamicStruct {
status: StatusCode,
ctx: (),
}
}You can even write arbitrary code!
#[status_code]
pub enum Error {
#[pattern((ctx))]
#[code({
let result = StatusCode::try_from(ctx.status_code()).unwrap();
return result
})]
Number(ErrorContext)
}The interior of the code attribute, as you’ve probably figured out, is the contents of the match arm (which is what the macro expands to). The interior of the pattern attribute is the binding pattern to which to bind variables to. Note that the name of the variant should not be included here.
match enum {
Variant #pattern => #attribute,
...
}Pattern is optional, being filled in by an ignore-all if not set. Code is only optional if a default status code is set in the top-level status_code attribute.
Find out what status code something has using the as_status_code function.
pub fn endpoint(...) -> impl IntoResponse {
let user = fetch_user(cookies);
if let Err(err) = user {
return (err.as_status_code(), err.to_string())
}
}