1use axum::{
9 http::StatusCode,
10 response::{IntoResponse, Response},
11};
12use thiserror::Error;
13
14#[derive(Error, Debug)]
19pub enum AppError {
20 #[error("远程API请求错误: {0}")]
24 Remote(#[from] reqwest::Error),
25
26 #[error("无效的输入参数: {0}")]
30 BadRequest(String),
31
32 #[error("请求的资源不存在")]
36 NotFound,
37
38 #[error("服务器内部错误: {0}")]
42 Internal(String),
43
44 #[error("配置错误: {0}")]
48 Config(String),
49}
50
51impl IntoResponse for AppError {
52 fn into_response(self) -> Response {
62 let (status, message) = match self {
63 AppError::Remote(ref e) if e.is_timeout() => (StatusCode::REQUEST_TIMEOUT, "请求超时"),
64 AppError::Remote(_) => (StatusCode::BAD_GATEWAY, "远程服务暂时不可用"),
65 AppError::BadRequest(ref msg) => (StatusCode::BAD_REQUEST, msg.as_str()),
66 AppError::NotFound => (StatusCode::NOT_FOUND, "请求的资源不存在"),
67 AppError::Internal(_) => (StatusCode::INTERNAL_SERVER_ERROR, "服务器内部错误"),
68 AppError::Config(_) => (StatusCode::INTERNAL_SERVER_ERROR, "配置错误"),
69 };
70
71 let body = serde_json::json!({
72 "error": message,
73 "code": status.as_u16()
74 });
75
76 (status, axum::Json(body)).into_response()
77 }
78}