use actix_web::{ResponseError, http::StatusCode, HttpResponse}; use serde::Serialize; use std::fmt; #[derive(Debug, Serialize)] pub struct ErrorResponse { pub success: bool, pub data: Option, #[serde(skip_serializing_if = "Option::is_none")] pub error: Option, } impl ErrorResponse { pub fn success(data: T) -> Self { Self { success: true, data: Some(data), error: None, } } pub fn error(msg: impl Into) -> Self { Self { success: false, data: None, error: Some(msg.into()), } } } impl ErrorResponse { pub fn to_json_response(self) -> HttpResponse { HttpResponse::Ok().json(self) } } impl ErrorResponse<()> { pub fn to_error_response(&self, status: StatusCode) -> HttpResponse { let body = serde_json::json!({ "success": false, "error": self.error.clone().unwrap_or_else(|| "Unknown error".to_string()) }); HttpResponse::build(status).json(body) } } #[derive(Debug)] pub enum AppError { Unauthorized(String), Forbidden(String), NotFound(String), BadRequest(String), Internal(String), Database(String), TooManyRequests(String), ServiceUnavailable(String), } impl fmt::Display for AppError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { AppError::Unauthorized(msg) => write!(f, "{}", msg), AppError::Forbidden(msg) => write!(f, "{}", msg), AppError::NotFound(msg) => write!(f, "{}", msg), AppError::BadRequest(msg) => write!(f, "{}", msg), AppError::Internal(msg) => write!(f, "{}", msg), AppError::Database(msg) => write!(f, "{}", msg), AppError::TooManyRequests(msg) => write!(f, "{}", msg), AppError::ServiceUnavailable(msg) => write!(f, "{}", msg), } } } impl ResponseError for AppError { fn status_code(&self) -> StatusCode { match self { AppError::Unauthorized(_) => StatusCode::UNAUTHORIZED, AppError::Forbidden(_) => StatusCode::FORBIDDEN, AppError::NotFound(_) => StatusCode::NOT_FOUND, AppError::BadRequest(_) => StatusCode::BAD_REQUEST, AppError::Internal(_) | AppError::Database(_) => StatusCode::INTERNAL_SERVER_ERROR, AppError::TooManyRequests(_) => StatusCode::TOO_MANY_REQUESTS, AppError::ServiceUnavailable(_) => StatusCode::SERVICE_UNAVAILABLE, } } fn error_response(&self) -> actix_web::HttpResponse { let error_message = self.to_string(); let status_code = self.status_code().as_u16(); let html = format!(r#" 错误 {status_code}
{status_code}

{error_title}

{error_message}

请返回小程序重新生成新的下载链接

如果问题持续存在,请联系技术支持
"#, error_title = match self { AppError::Unauthorized(_) => "认证失败", AppError::Forbidden(_) => "权限不足", AppError::NotFound(_) => "内容未找到", AppError::BadRequest(_) => "请求无效", AppError::Internal(_) | AppError::Database(_) => "服务器错误", AppError::TooManyRequests(_) => "请求过于频繁", AppError::ServiceUnavailable(_) => "服务暂不可用", } ); HttpResponse::build(self.status_code()) .content_type("text/html; charset=utf-8") .body(html) } }