1 unstable release
0.1.0 | Oct 2, 2021 |
---|
#9 in #responder
5KB
JsonResponder
This is an helper crate for the backend, which provides the JsonResponder
macro, to easily derive errors in JSON format for Rocket.
The format is as follows:
{
"code": "{responsecode}",
"error": "{readableerror}"
}
Where:
responsecode
is an machine readable code, this is from an mandantorycode()
function in the implemented struct.readableerror
is an error for humans, often derrived using thethiserror
crate.
Example
To create an error enum, make something like this:
#[derive(Error, Debug, JsonResponder)]
pub enum RouteError {
#[error("Access denied.")]
AccessDenied,
#[error("An internal database error occured.")]
DatabaseError(#[from] sqlx::Error),
}
impl<'a> RouteError {
fn code(&self) -> &'a str {
match self {
RouteError::AccessDenied => "accessdenied",
RouteError::DatabaseError(_) => "databaseerror",
}
}
}
impl From<RouteError> for Status {
fn from(err: RouteError) -> Self {
match err {
RouteError::AccessDenied => Status::Unauthorized,
RouteError::DatabaseError(_) => Status::InternalServerError,
}
}
}
Now you can use this in routes like this:
#[get("/whoami")]
pub async fn route(
pool: &State<Pool<Postgres>>,
) -> Result<Json<Response>, RouteError> {
let mut conn = pool.acquire().await?;
let account = logic::account::Account::find(&mut conn, "some-name").await?;
Ok(Json(Response { account }))
}
If the two called functions will either return RouteError
or RouteError
, then the responder will automatically convert the error to valid JSON.
For example, when the pool fails to aquire an connection, the response will be something like:
{
"code": "databaseerror",
"error": "An internal database error occured."
}
Because RouteError
has an From
implementation into Status
, the correct status will also be set to an 500 internal server error
.
Dependencies
~16–47MB
~817K SLoC