use erp_core::error::AppError; /// Config module error types. #[derive(Debug, thiserror::Error)] pub enum ConfigError { #[error("验证失败: {0}")] Validation(String), #[error("资源未找到: {0}")] NotFound(String), #[error("键已存在: {0}")] DuplicateKey(String), #[error("编号序列耗尽: {0}")] NumberingExhausted(String), #[error("版本冲突: 数据已被其他操作修改,请刷新后重试")] VersionMismatch, } impl From> for ConfigError { fn from(err: sea_orm::TransactionError) -> Self { match err { sea_orm::TransactionError::Connection(err) => ConfigError::Validation(err.to_string()), sea_orm::TransactionError::Transaction(inner) => inner, } } } impl From for AppError { fn from(err: ConfigError) -> Self { match err { ConfigError::Validation(s) => AppError::Validation(s), ConfigError::NotFound(s) => AppError::NotFound(s), ConfigError::DuplicateKey(s) => AppError::Conflict(s), ConfigError::NumberingExhausted(s) => AppError::Internal(s), ConfigError::VersionMismatch => AppError::VersionMismatch, } } } pub type ConfigResult = Result; #[cfg(test)] mod tests { use super::*; use erp_core::error::AppError; #[test] fn config_error_validation_maps_to_app_validation() { let app: AppError = ConfigError::Validation("字段不能为空".to_string()).into(); match app { AppError::Validation(msg) => assert_eq!(msg, "字段不能为空"), other => panic!("期望 Validation,实际得到 {:?}", other), } } #[test] fn config_error_not_found_maps_to_app_not_found() { let app: AppError = ConfigError::NotFound("字典不存在".to_string()).into(); match app { AppError::NotFound(msg) => assert_eq!(msg, "字典不存在"), other => panic!("期望 NotFound,实际得到 {:?}", other), } } #[test] fn config_error_duplicate_key_maps_to_app_conflict() { let app: AppError = ConfigError::DuplicateKey("编码已存在".to_string()).into(); match app { AppError::Conflict(msg) => assert_eq!(msg, "编码已存在"), other => panic!("期望 Conflict,实际得到 {:?}", other), } } #[test] fn config_error_numbering_exhausted_maps_to_app_internal() { let app: AppError = ConfigError::NumberingExhausted("序列已耗尽".to_string()).into(); match app { AppError::Internal(msg) => assert!(msg.contains("序列已耗尽")), other => panic!("期望 Internal,实际得到 {:?}", other), } } #[test] fn config_error_version_mismatch_maps_to_app_version_mismatch() { let app: AppError = ConfigError::VersionMismatch.into(); match app { AppError::VersionMismatch => {} other => panic!("期望 VersionMismatch,实际得到 {:?}", other), } } #[test] fn config_error_display_messages() { // 验证各变体的 Display 输出包含中文描述 assert!(ConfigError::Validation("test".into()).to_string().contains("验证失败")); assert!(ConfigError::NotFound("test".into()).to_string().contains("资源未找到")); assert!(ConfigError::DuplicateKey("test".into()).to_string().contains("键已存在")); assert!(ConfigError::NumberingExhausted("test".into()).to_string().contains("编号序列耗尽")); assert!(ConfigError::VersionMismatch.to_string().contains("版本冲突")); } #[test] fn transaction_error_connection_maps_to_validation() { // TransactionError::Connection 应该转换为 ConfigError::Validation let config_err: ConfigError = sea_orm::TransactionError::Connection(sea_orm::DbErr::Conn(sea_orm::RuntimeErr::Internal("连接失败".to_string()))) .into(); match config_err { ConfigError::Validation(msg) => assert!(msg.contains("连接失败")), other => panic!("期望 Validation,实际得到 {:?}", other), } } }