orion_error/core/
universal.rs1use thiserror::Error;
2
3use super::ErrorCode;
4
5#[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#[derive(Debug, Error, PartialEq, Clone)]
26#[cfg_attr(feature = "serde", derive(serde::Serialize))]
27pub enum UvsReason {
28 #[error("validation error")]
31 ValidationError,
32
33 #[error("business logic error")]
35 BusinessError,
36
37 #[error("run rule error")]
39 RunRuleError,
40
41 #[error("not found error")]
43 NotFoundError,
44
45 #[error("permission error")]
47 PermissionError,
48
49 #[error("data error")]
52 DataError,
53
54 #[error("system error")]
56 SystemError,
57
58 #[error("network error")]
60 NetworkError,
61
62 #[error("resource error")]
64 ResourceError,
65
66 #[error("timeout error")]
68 TimeoutError,
69
70 #[error("configuration error << {0}")]
73 ConfigError(ConfErrReason),
74
75 #[error("external service error")]
77 ExternalError,
78
79 #[error("BUG :logic error")]
81 LogicError,
82}
83
84impl UvsReason {
85 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 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 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 pub fn external_error() -> Self {
142 Self::ExternalError
143 }
144
145 pub fn logic_error() -> Self {
146 Self::LogicError
147 }
148}
149
150pub 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 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 UvsReason::DataError => 200,
224 UvsReason::SystemError => 201,
225 UvsReason::NetworkError => 202,
226 UvsReason::ResourceError => 203,
227 UvsReason::TimeoutError => 204,
228
229 UvsReason::ConfigError(_) => 300,
231 UvsReason::ExternalError => 301,
232 }
233 }
234}
235
236impl UvsReason {
237 pub fn is_retryable(&self) -> bool {
240 match self {
241 UvsReason::NetworkError => true,
243 UvsReason::TimeoutError => true,
244 UvsReason::ResourceError => true,
245 UvsReason::SystemError => true,
246 UvsReason::ExternalError => true,
247
248 UvsReason::ValidationError => false,
250 UvsReason::BusinessError => false,
251 UvsReason::RunRuleError => false,
252 UvsReason::NotFoundError => false,
253 UvsReason::PermissionError => false,
254
255 UvsReason::ConfigError(_) => false,
257 UvsReason::DataError => false,
258 UvsReason::LogicError => false,
259 }
260 }
261
262 pub fn is_high_severity(&self) -> bool {
265 match self {
266 UvsReason::SystemError => true,
268 UvsReason::ResourceError => true,
269 UvsReason::ConfigError(_) => true,
270
271 _ => false,
273 }
274 }
275
276 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 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 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 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}