diff --git a/Cargo.toml b/Cargo.toml index 20d6a4d..da4062d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "common-telemetry" -version = "0.1.2" +version = "0.1.3" edition = "2024" description = "Microservice infrastructure library" diff --git a/src/error.rs b/src/error.rs index e89bf4f..7aa51d4 100644 --- a/src/error.rs +++ b/src/error.rs @@ -157,13 +157,16 @@ impl AppError { // 映射 HTTP 状态码 (给网关/浏览器看) fn http_status(&self) -> StatusCode { match self { - AppError::DbError(_) - | AppError::CacheError(_) - | AppError::ExternalReqError(_) + #[cfg(feature = "with-sqlx")] + AppError::DbError(_) => StatusCode::INTERNAL_SERVER_ERROR, + #[cfg(feature = "with-redis")] + AppError::CacheError(_) => StatusCode::INTERNAL_SERVER_ERROR, + #[cfg(feature = "with-anyhow")] + AppError::AnyhowError(_) => StatusCode::INTERNAL_SERVER_ERROR, + AppError::ExternalReqError(_) | AppError::MqError(_) | AppError::IoError(_) - | AppError::SerdeError(_) - | AppError::AnyhowError(_) => StatusCode::INTERNAL_SERVER_ERROR, + | AppError::SerdeError(_) => StatusCode::INTERNAL_SERVER_ERROR, // 401 Unauthorized AppError::AuthError(_) | AppError::MissingAuthHeader @@ -184,6 +187,8 @@ impl AppError { AppError::RateLimitExceeded => StatusCode::TOO_MANY_REQUESTS, // 400 Bad Request (默认) + #[cfg(feature = "with-validator")] + AppError::ValidationError(_) => StatusCode::BAD_REQUEST, _ => StatusCode::BAD_REQUEST, } } @@ -192,12 +197,14 @@ impl AppError { fn biz_code(&self) -> BizCode { match self { // Infra + #[cfg(feature = "with-sqlx")] AppError::DbError(_) => BizCode::DbError, + #[cfg(feature = "with-redis")] AppError::CacheError(_) => BizCode::CacheError, AppError::ExternalReqError(_) => BizCode::ExternalServiceError, - AppError::MqError(_) | AppError::IoError(_) | AppError::AnyhowError(_) => { - BizCode::ServerError - } + #[cfg(feature = "with-anyhow")] + AppError::AnyhowError(_) => BizCode::ServerError, + AppError::MqError(_) | AppError::IoError(_) => BizCode::ServerError, AppError::SerdeError(_) => BizCode::SerializationError, // Auth @@ -212,6 +219,7 @@ impl AppError { AppError::NotFound(_) => BizCode::ResourceNotFound, AppError::AlreadyExists(_) => BizCode::ResourceAlreadyExists, AppError::BadRequest(_) => BizCode::BadRequest, + #[cfg(feature = "with-validator")] AppError::ValidationError(_) => BizCode::ValidationError, // Biz @@ -230,7 +238,8 @@ impl IntoResponse for AppError { // 但这里为了演示,我们先直接使用 self.to_string() // 建议:在生产环境针对 DbError/AnyhowError 返回统一的 "Internal Server Error" let message = match self { - AppError::DbError(_) | AppError::AnyhowError(_) => { + #[cfg(feature = "with-sqlx")] + AppError::DbError(_) => { // 如果是生产环境(release模式),隐藏敏感信息 #[cfg(not(debug_assertions))] { @@ -241,6 +250,30 @@ impl IntoResponse for AppError { self.to_string() } } + // 生产环境隐藏 Anyhow 报错 + #[cfg(feature = "with-anyhow")] + AppError::AnyhowError(_) => { + #[cfg(not(debug_assertions))] + { + "Internal server error".to_string() + } + #[cfg(debug_assertions)] + { + self.to_string() + } + } + // Redis 报错 + #[cfg(feature = "with-redis")] + AppError::CacheError(_) => { + #[cfg(not(debug_assertions))] + { + "Cache internal error".to_string() + } + #[cfg(debug_assertions)] + { + self.to_string() + } + } _ => self.to_string(), };