8个版本 (4个主要版本)

5.0.1 2023年12月29日
5.0.0 2023年11月28日
4.1.0 2023年10月29日
3.0.0 2023年9月6日
1.0.0 2023年6月30日

HTTP服务器 中排名 #225

Download history 16/week @ 2024-04-08 39/week @ 2024-04-15 19/week @ 2024-04-22 73/week @ 2024-04-29 125/week @ 2024-05-13 125/week @ 2024-05-20 80/week @ 2024-05-27 7/week @ 2024-06-03 45/week @ 2024-06-10 70/week @ 2024-06-24 52/week @ 2024-07-01 88/week @ 2024-07-08 131/week @ 2024-07-15 100/week @ 2024-07-22

每月下载量 372

MIT 许可证

18KB
266

Axum路由错误

Axum路由的常用错误响应

crate docs


此库存在是为了封装从Axum路由返回错误时的一些常用模式。这些模式包括

  • 想要以JSON对象的形式返回错误响应
  • 自动将路由处理器中引发的错误转换为标准化的JSON响应
  • 提供适合公共使用的适当默认错误消息,这考虑到了正在使用的状态码
  • 有时需要可选地添加额外的数据到错误JSON输出

基本教程

以下是一个模拟示例路由,用于下载用户对象

use ::axum::extract::State;
use ::axum_route_error::RouteError;
use ::sea_orm::DatabaseConnection;

pub async fn route_get_user(
    State(ref db): State<DatabaseConnection>,
    Path(username): Path<String>
) -> Result<ExampleUser, RouteError> {
    // If this errors, then a `RouteError::new_internal_server()` is returned.
    let user = get_user_from_database(db, &username).await?;

    Ok(user)
}

如果 get_user_from_database 函数返回错误,那么处理器将返回一个Response。该Response将具有500状态码(内部错误),并返回以下输出

{
  "error": "An unexpected error occurred"
}

不同的 RouteError 类型

假设 get_user_from_database 返回一个 Result<Option, Error>。如果它返回错误(如上所示),我们想返回500,如果用户未找到,则更改代码以返回404。

use ::axum::extract::State;
use ::axum_route_error::RouteError;
use ::sea_orm::DatabaseConnection;

pub async fn route_get_user(
    State(ref db): State<DatabaseConnection>,
    Path(username): Path<String>
) -> Result<ExampleUser, RouteError> {
    let user = get_user_from_database(db, &username).await?
      // This additional line will return a 404 if the user is not found.
      .ok_or_else(|| RouteError::new_not_found())?;

    Ok(user)
}

如果用户未找到(get_user_from_database 返回 None),则这将返回一个包含以下JSON的404 Response

{
  "error": "The resource was not found"
}

添加额外的错误数据

接下来,让我们向错误添加额外的信息。不仅仅是错误消息。

这可以通过创建一个新的使用Serde序列化的类型来实现,然后将此添加到 RouteError 中。

use ::axum::extract::State;
use ::axum_route_error::RouteError;
use ::sea_orm::DatabaseConnection;
use ::serde::Deserialize;
use ::serde::Serialize;

// The additional error information needs to derive these three traits.
#[derive(Deserialize, Serialize, Debug)]
pub struct UserErrorInformation {
  pub username: String
}

pub async fn route_get_user(
    State(ref db): State<DatabaseConnection>,
    Path(username): Path<String>
// The `RouteError` needs the additional data marked here
) -> Result<ExampleUser, RouteError<UserErrorInformation>> {
    let user = get_user_from_database(db, &username).await?
      .ok_or_else(move || {
        // Then you can add the data through method chaining
        RouteError::new_not_found()
          .set_error_data(UserErrorInformation {
            username,
          })
      })?;

    Ok(user)
}

如果用户未找到(get_user_from_database 返回 None),则这将返回一个包含以下JSON的404 Response

{
  "error": "The resource was not found",
  "username": "<the-username>"
}

使内部错误公开

有时你 想要 使内部错误公开,例如对于内部服务。

为此,您可以使用 RouteInternalError。它与前者相同,但向响应添加了 internal_error 信息。

依赖项

~7–10MB
~186K SLoC