feat: 完善生产级 Rust Web 模板
This commit is contained in:
+36
-51
@@ -5,38 +5,6 @@ use axum::{
|
||||
Json,
|
||||
};
|
||||
|
||||
/// 应用错误类型
|
||||
#[allow(dead_code)]
|
||||
pub struct AppError(pub anyhow::Error);
|
||||
|
||||
impl IntoResponse for AppError {
|
||||
fn into_response(self) -> Response {
|
||||
tracing::error!("Application error: {:?}", self.0);
|
||||
|
||||
let (status, message) = match self.0.downcast_ref::<&str>() {
|
||||
Some(&"not_found") => (StatusCode::NOT_FOUND, "Resource not found"),
|
||||
Some(&"unauthorized") => (StatusCode::UNAUTHORIZED, "Unauthorized"),
|
||||
_ => (StatusCode::INTERNAL_SERVER_ERROR, "Internal server error"),
|
||||
};
|
||||
|
||||
let body = ApiResponse::<()> {
|
||||
code: status.as_u16(),
|
||||
message: message.to_string(),
|
||||
data: None,
|
||||
};
|
||||
|
||||
(status, Json(body)).into_response()
|
||||
}
|
||||
}
|
||||
|
||||
// 为具体类型实现 From
|
||||
impl From<anyhow::Error> for AppError {
|
||||
fn from(err: anyhow::Error) -> Self {
|
||||
Self(err)
|
||||
}
|
||||
}
|
||||
|
||||
/// 统一的 API 错误响应结构
|
||||
#[derive(Debug)]
|
||||
pub struct ErrorResponse {
|
||||
pub status: StatusCode,
|
||||
@@ -45,29 +13,44 @@ pub struct ErrorResponse {
|
||||
|
||||
impl ErrorResponse {
|
||||
pub fn new(message: impl Into<String>) -> Self {
|
||||
Self::bad_request(message)
|
||||
}
|
||||
pub fn bad_request(message: impl Into<String>) -> Self {
|
||||
Self {
|
||||
status: StatusCode::BAD_REQUEST,
|
||||
message: message.into(),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn not_found(message: impl Into<String>) -> Self {
|
||||
Self {
|
||||
status: StatusCode::NOT_FOUND,
|
||||
message: message.into(),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn unauthorized(message: impl Into<String>) -> Self {
|
||||
Self {
|
||||
status: StatusCode::UNAUTHORIZED,
|
||||
message: message.into(),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn not_found(message: impl Into<String>) -> Self {
|
||||
Self {
|
||||
status: StatusCode::NOT_FOUND,
|
||||
message: message.into(),
|
||||
}
|
||||
}
|
||||
pub fn too_many_requests(message: impl Into<String>) -> Self {
|
||||
Self {
|
||||
status: StatusCode::TOO_MANY_REQUESTS,
|
||||
message: message.into(),
|
||||
}
|
||||
}
|
||||
pub fn payload_too_large(message: impl Into<String>) -> Self {
|
||||
Self {
|
||||
status: StatusCode::PAYLOAD_TOO_LARGE,
|
||||
message: message.into(),
|
||||
}
|
||||
}
|
||||
pub fn unavailable(message: impl Into<String>) -> Self {
|
||||
Self {
|
||||
status: StatusCode::SERVICE_UNAVAILABLE,
|
||||
message: message.into(),
|
||||
}
|
||||
}
|
||||
pub fn internal(message: impl Into<String>) -> Self {
|
||||
Self {
|
||||
status: StatusCode::INTERNAL_SERVER_ERROR,
|
||||
@@ -78,12 +61,14 @@ impl ErrorResponse {
|
||||
|
||||
impl IntoResponse for ErrorResponse {
|
||||
fn into_response(self) -> Response {
|
||||
let body = ApiResponse::<()> {
|
||||
code: self.status.as_u16(),
|
||||
message: self.message,
|
||||
data: None,
|
||||
};
|
||||
|
||||
(self.status, Json(body)).into_response()
|
||||
(
|
||||
self.status,
|
||||
Json(ApiResponse::<()> {
|
||||
code: self.status.as_u16(),
|
||||
message: self.message,
|
||||
data: None,
|
||||
}),
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user