2 个不稳定版本
0.1.0 | 2023 年 12 月 27 日 |
---|---|
0.0.0 | 2023 年 12 月 27 日 |
#9 在 #http-status
14KB
162 代码行
Axum-dyn-error
为 Axum HTTP 处理器实现动态错误处理
[dependencies]
axum-dyn-error = "0.1"
仅支持 axum v0.6
此crate提供创建和处理动态HTTP错误的基础逻辑。
通过在错误上实现HttpError
trait,您可以自定义错误及其在错误响应中的显示方式。
我建议使用thiserror
来定义您的用户界面错误类型。
为了使用动态错误处理,您应将您的[Result]返回类型替换为axum_dyn_error
中的[HttpResult]类型。
use axum_dyn_error::{HttpResult, HttpError, StatusCode};
use thiserror::Error;
use axum::{extract::Path, Json};
#[derive(Debug, Error)]
pub enum ExampleError {
#[error("User not found")]
MissingUser,
#[error("Username was invalid")]
InvalidUsername
}
impl HttpError for ExampleError {
/// Customize the HTTP status code
fn status(&self) -> StatusCode {
match self {
ExampleError::MissingUser => StatusCode::NOT_FOUND,
ExampleError::InvalidUsername => StatusCode::BAD_REQUEST
}
}
}
/// Dummy structure representing a user
pub struct User;
/// Mock function for finding a user by id
pub async fn get_user_by_id(user_id: u32) -> Option<User> { unimplemented!() }
/// Example handler
pub async fn example_handler(
Path(user_id): Path<u32>
) -> HttpResult<Json<User>> {
let user = get_user_by_id(user_id)
.await
.ok_or(ExampleError::MissingUser)?;
Ok(Json(user))
}
Anyhow 支持
Axum-dyn-error 通过anyhow
功能标志支持anyhow
错误,默认情况下启用hide-anyhow
功能标志,这会阻止将anyhow错误消息包含在错误响应中,而是响应“服务器错误”。
use axum_dyn_error::{HttpResult, HttpError, StatusCode};
use axum::{extract::Path, Json};
use anyhow::anyhow;
/// Dummy structure representing a user
pub struct User;
/// Mock function for finding a user by id
pub async fn get_user_by_id(user_id: u32) -> Option<User> { unimplemented!() }
/// Example handler
pub async fn example_handler(
Path(user_id): Path<u32>
) -> HttpResult<Json<User>> {
let user = get_user_by_id(user_id)
.await
.ok_or(anyhow!("Missing user"))?;
Ok(Json(user))
}
使用[AnyhowStatusExt],anyhow错误类型可以关联HTTP状态码,默认情况下anyhow错误仅使用“500 内部服务器错误”。
use axum_dyn_error::{HttpResult, HttpError, StatusCode, anyhow::AnyhowStatusExt};
use axum::{extract::Path, Json};
use anyhow::anyhow;
/// Dummy structure representing a user
pub struct User;
/// Mock function for finding a user by id
pub async fn get_user_by_id(user_id: u32) -> Option<User> { unimplemented!() }
/// Example handler
pub async fn example_handler(
Path(user_id): Path<u32>
) -> HttpResult<Json<User>> {
let user = get_user_by_id(user_id)
.await
.ok_or(
anyhow!("Missing user")
.status(StatusCode::NOT_FOUND)
)?;
Ok(Json(user))
}
自定义响应
默认情况下,从错误生成的响应使用“原因”作为文本响应体。您可以通过创建一个结构并在此结构上实现IntoHttpErrorResponse
来更改此设置。
use axum_dyn_error::{HttpResult, HttpError, IntoHttpErrorResponse};
use axum::response::{Response, IntoResponse};
pub struct CustomErrorResponse;
impl IntoHttpErrorResponse for CustomErrorResponse {
fn into_response(error: Box<dyn HttpError>) -> Response {
// Your logic to create the response from the error example:
(error.status(), error.reason()).into_response()
}
}
// You can then alias the HttpResult type
pub type MyHttpResult<T> = HttpResult<T, CustomErrorResponse>;
crate 功能
默认功能是 ["log", "hide-anyhow"]
功能 | 描述 |
---|---|
log | 使用log::error! 创建的错误记录 |
anyhow | 添加了对处理anyhow 错误类型的支持 |
hide-anyhow | 在HTTP响应中将anyhow错误消息替换为通用服务器错误消息 |
依赖
~1.6–2.4MB
~47K SLoC