feat: 完善生产级 Rust Web 模板

This commit is contained in:
2026-07-21 16:00:03 +08:00
parent fb30d5da1a
commit ce89569bf3
58 changed files with 2042 additions and 349 deletions
+36 -51
View File
@@ -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()
}
}