Skip to main content

orion_error/core/
universal.rs

1use thiserror::Error;
2
3use super::ErrorCode;
4
5/// Configuration error sub-classification
6/// 配置错误子分类
7#[derive(Debug, Error, PartialEq, Clone)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize))]
9pub enum ConfErrReason {
10    #[error("core config")]
11    Core,
12    #[error("feature config error")]
13    Feature,
14    #[error("dynamic config error")]
15    Dynamic,
16}
17
18/// Universal error reason classification with clear hierarchical structure
19/// 统一错误原因分类 - 采用清晰的分层结构
20///
21/// # Error Code Ranges
22/// - 100-199: Business Layer Errors (业务层错误)
23/// - 200-299: Infrastructure Layer Errors (基础设施层错误)
24/// - 300-399: Configuration & External Layer Errors (配置和外部层错误)
25#[derive(Debug, Error, PartialEq, Clone)]
26#[cfg_attr(feature = "serde", derive(serde::Serialize))]
27pub enum UvsReason {
28    // === Business Layer Errors (100-199) ===
29    /// Input validation errors (格式错误、参数校验失败等)
30    #[error("validation error")]
31    ValidationError,
32
33    /// Business logic rule violations (业务规则违反、状态冲突等)
34    #[error("business logic error")]
35    BusinessError,
36
37    /// Business logic rule violations (业务规则违反、状态冲突等)
38    #[error("run rule error")]
39    RunRuleError,
40
41    /// Resource not found (查询的资源不存在)
42    #[error("not found error")]
43    NotFoundError,
44
45    /// Permission and authorization errors (权限不足、认证失败)
46    #[error("permission error")]
47    PermissionError,
48
49    // === Infrastructure Layer Errors (200-299) ===
50    /// Database and data processing errors (数据库操作、数据格式错误)
51    #[error("data error")]
52    DataError,
53
54    /// File system and OS-level errors (文件系统、操作系统错误)
55    #[error("system error")]
56    SystemError,
57
58    /// Network connectivity and protocol errors (网络连接、HTTP请求错误)
59    #[error("network error")]
60    NetworkError,
61
62    /// Resource exhaustion (内存不足、磁盘空间不足等)
63    #[error("resource error")]
64    ResourceError,
65
66    /// Operation timeouts (操作超时)
67    #[error("timeout error")]
68    TimeoutError,
69
70    // === Configuration & External Layer Errors (300-399) ===
71    /// Configuration-related errors (配置相关错误)
72    #[error("configuration error << {0}")]
73    ConfigError(ConfErrReason),
74
75    /// Third-party service errors (第三方服务错误)
76    #[error("external service error")]
77    ExternalError,
78
79    /// Third-party service errors (第三方服务错误)
80    #[error("BUG :logic error")]
81    LogicError,
82}
83
84impl UvsReason {
85    // === Configuration Error Constructors ===
86    pub fn core_conf() -> Self {
87        Self::ConfigError(ConfErrReason::Core)
88    }
89
90    pub fn feature_conf() -> Self {
91        Self::ConfigError(ConfErrReason::Feature)
92    }
93
94    pub fn dynamic_conf() -> Self {
95        Self::ConfigError(ConfErrReason::Dynamic)
96    }
97
98    // === Business Layer Constructors ===
99    pub fn validation_error() -> Self {
100        Self::ValidationError
101    }
102
103    pub fn business_error() -> Self {
104        Self::BusinessError
105    }
106
107    pub fn rule_error() -> Self {
108        Self::RunRuleError
109    }
110
111    pub fn not_found_error() -> Self {
112        Self::NotFoundError
113    }
114
115    pub fn permission_error() -> Self {
116        Self::PermissionError
117    }
118
119    // === Infrastructure Layer Constructors ===
120    pub fn data_error() -> Self {
121        Self::DataError
122    }
123
124    pub fn system_error() -> Self {
125        Self::SystemError
126    }
127
128    pub fn network_error() -> Self {
129        Self::NetworkError
130    }
131
132    pub fn resource_error() -> Self {
133        Self::ResourceError
134    }
135
136    pub fn timeout_error() -> Self {
137        Self::TimeoutError
138    }
139
140    // === External Layer Constructors ===
141    pub fn external_error() -> Self {
142        Self::ExternalError
143    }
144
145    pub fn logic_error() -> Self {
146        Self::LogicError
147    }
148}
149
150/// Unified constructor helpers for types that can be converted from `UvsReason`.
151pub trait UvsFrom: From<UvsReason> + Sized {
152    fn from_conf() -> Self {
153        Self::from(UvsReason::core_conf())
154    }
155
156    fn from_conf_reason(reason: ConfErrReason) -> Self {
157        Self::from(UvsReason::ConfigError(reason))
158    }
159
160    fn from_data() -> Self {
161        Self::from(UvsReason::data_error())
162    }
163
164    fn from_sys() -> Self {
165        Self::from(UvsReason::system_error())
166    }
167
168    fn from_biz() -> Self {
169        Self::from(UvsReason::business_error())
170    }
171
172    fn from_logic() -> Self {
173        Self::from(UvsReason::logic_error())
174    }
175
176    fn from_rule() -> Self {
177        Self::from(UvsReason::rule_error())
178    }
179
180    fn from_res() -> Self {
181        Self::from(UvsReason::resource_error())
182    }
183
184    fn from_net() -> Self {
185        Self::from(UvsReason::network_error())
186    }
187
188    fn from_timeout() -> Self {
189        Self::from(UvsReason::timeout_error())
190    }
191
192    fn from_validation() -> Self {
193        Self::from(UvsReason::validation_error())
194    }
195
196    fn from_not_found() -> Self {
197        Self::from(UvsReason::not_found_error())
198    }
199
200    fn from_permission() -> Self {
201        Self::from(UvsReason::permission_error())
202    }
203
204    fn from_external() -> Self {
205        Self::from(UvsReason::external_error())
206    }
207}
208
209impl<T> UvsFrom for T where T: From<UvsReason> {}
210
211impl ErrorCode for UvsReason {
212    fn error_code(&self) -> i32 {
213        match self {
214            // === Business Layer Errors (100-199) ===
215            UvsReason::ValidationError => 100,
216            UvsReason::BusinessError => 101,
217            UvsReason::NotFoundError => 102,
218            UvsReason::PermissionError => 103,
219            UvsReason::LogicError => 104,
220            UvsReason::RunRuleError => 105,
221
222            // === Infrastructure Layer Errors (200-299) ===
223            UvsReason::DataError => 200,
224            UvsReason::SystemError => 201,
225            UvsReason::NetworkError => 202,
226            UvsReason::ResourceError => 203,
227            UvsReason::TimeoutError => 204,
228
229            // === Configuration & External Layer Errors (300-399) ===
230            UvsReason::ConfigError(_) => 300,
231            UvsReason::ExternalError => 301,
232        }
233    }
234}
235
236impl UvsReason {
237    /// Check if this error is retryable
238    /// 检查错误是否可重试
239    pub fn is_retryable(&self) -> bool {
240        match self {
241            // Infrastructure errors are often retryable
242            UvsReason::NetworkError => true,
243            UvsReason::TimeoutError => true,
244            UvsReason::ResourceError => true,
245            UvsReason::SystemError => true,
246            UvsReason::ExternalError => true,
247
248            // Business logic errors are generally not retryable
249            UvsReason::ValidationError => false,
250            UvsReason::BusinessError => false,
251            UvsReason::RunRuleError => false,
252            UvsReason::NotFoundError => false,
253            UvsReason::PermissionError => false,
254
255            // Configuration errors require manual intervention
256            UvsReason::ConfigError(_) => false,
257            UvsReason::DataError => false,
258            UvsReason::LogicError => false,
259        }
260    }
261
262    /// Check if this error should be logged with high severity
263    /// 检查错误是否需要高优先级记录
264    pub fn is_high_severity(&self) -> bool {
265        match self {
266            // System and infrastructure issues are high severity
267            UvsReason::SystemError => true,
268            UvsReason::ResourceError => true,
269            UvsReason::ConfigError(_) => true,
270
271            // Others are normal business operations
272            _ => false,
273        }
274    }
275
276    /// Get error category name for monitoring and metrics
277    /// 获取错误类别名称用于监控和指标
278    pub fn category_name(&self) -> &'static str {
279        match self {
280            UvsReason::ValidationError => "validation",
281            UvsReason::BusinessError => "business",
282            UvsReason::RunRuleError => "runrule",
283            UvsReason::NotFoundError => "not_found",
284            UvsReason::PermissionError => "permission",
285            UvsReason::DataError => "data",
286            UvsReason::SystemError => "system",
287            UvsReason::NetworkError => "network",
288            UvsReason::ResourceError => "resource",
289            UvsReason::TimeoutError => "timeout",
290            UvsReason::ConfigError(_) => "config",
291            UvsReason::ExternalError => "external",
292            UvsReason::LogicError => "logic",
293        }
294    }
295}
296
297#[cfg(test)]
298mod tests {
299    use super::*;
300
301    #[test]
302    fn test_error_code_ranges() {
303        // Business layer (100-199)
304        assert_eq!(UvsReason::validation_error().error_code(), 100);
305        assert_eq!(UvsReason::business_error().error_code(), 101);
306        assert_eq!(UvsReason::not_found_error().error_code(), 102);
307        assert_eq!(UvsReason::permission_error().error_code(), 103);
308
309        // Infrastructure layer (200-299)
310        assert_eq!(UvsReason::data_error().error_code(), 200);
311        assert_eq!(UvsReason::system_error().error_code(), 201);
312        assert_eq!(UvsReason::network_error().error_code(), 202);
313        assert_eq!(UvsReason::resource_error().error_code(), 203);
314        assert_eq!(UvsReason::timeout_error().error_code(), 204);
315
316        // Configuration & external layer (300-399)
317        assert_eq!(UvsReason::core_conf().error_code(), 300);
318        assert_eq!(UvsReason::external_error().error_code(), 301);
319    }
320
321    #[test]
322    fn test_retryable_errors() {
323        assert!(UvsReason::network_error().is_retryable());
324        assert!(UvsReason::timeout_error().is_retryable());
325        assert!(!UvsReason::validation_error().is_retryable());
326        assert!(!UvsReason::business_error().is_retryable());
327    }
328
329    #[test]
330    fn test_high_severity_errors() {
331        assert!(UvsReason::system_error().is_high_severity());
332        assert!(UvsReason::resource_error().is_high_severity());
333        assert!(!UvsReason::validation_error().is_high_severity());
334        assert!(!UvsReason::NotFoundError.is_high_severity());
335    }
336
337    #[test]
338    fn test_category_names() {
339        assert_eq!(UvsReason::network_error().category_name(), "network");
340        assert_eq!(UvsReason::business_error().category_name(), "business");
341        assert_eq!(UvsReason::core_conf().category_name(), "config");
342    }
343
344    #[test]
345    fn test_trait_implementations() {
346        let reason: UvsReason = <UvsReason as UvsFrom>::from_net();
347        assert_eq!(reason.error_code(), 202);
348
349        let reason: UvsReason = <UvsReason as UvsFrom>::from_validation();
350        assert_eq!(reason.error_code(), 100);
351
352        let reason: UvsReason = <UvsReason as UvsFrom>::from_external();
353        assert_eq!(reason.error_code(), 301);
354    }
355}