#error #rocket #json #responder #macro #macro-derive #server

jsonresponder

为Rocket提供的错误宏的JSON响应器

1 个不稳定发布

0.1.0 2021年10月2日

#9#responder

MIT 许可证

5KB

JsonResponder

这是一个后端辅助crate,它提供了JsonResponder宏,可以轻松地为Rocket生成JSON格式的错误。

格式如下

{
    "code": "{responsecode}",
    "error": "{readableerror}"
}

其中

  • responsecode是一个机器可读的代码,这是从实现的结构体中的强制性的code()函数中来的。
  • readableerror是供人类阅读的错误,通常使用thiserror crate生成。

示例

要创建一个错误枚举,可以这样做

#[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,
        }
    }
}

现在您可以在这样的路由中使用它

#[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 }))
}

如果两个调用的函数将返回RouteErrorRouteError,则响应器将自动将错误转换为有效的JSON。例如,当连接池无法获取连接时,响应将类似于

{
    "code": "databaseerror",
    "error": "An internal database error occured."
}

因为RouteError实现了到StatusFrom实现,所以也将设置正确的状态为500内部服务器错误

依赖

~16–51MB
~827K SLoC