orion-error 0.6.0

Struct Error for Large Project
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
# orion-error
[Chinese Version](#orion-error-zh)

Structured error handling library for building large-scale applications, providing complete error context tracking and flexible aggregation strategies.

[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/galaxy-sec/orion-error)

[![CI](https://github.com/galaxy-sec/orion-error/workflows/CI/badge.svg)](https://github.com/galaxy-sec/orion-error/actions)
[![Coverage Status](https://codecov.io/gh/galaxy-sec/orion-error/branch/main/graph/badge.svg)](https://codecov.io/gh/galaxy-sec/orion-error)
[![crates.io](https://img.shields.io/crates/v/orion-error.svg)](https://crates.io/crates/orion-error)

## Features

- **Structured Errors**: Support multi-layer error aggregation with full error chain
- **Hierarchical Error Classification**: Three-tier classification system with clear boundaries
  - **Business Layer (100-199)**: User-facing expected errors
  - **Infrastructure Layer (200-299)**: System-level failures
  - **Configuration & External Layer (300-399)**: Environment and third-party issues
- **Error Types**: 10 specific error types with semantic meaning
- **Smart Error Analysis**: Built-in retryability and severity assessment
- **Context Tracing**: Support multi-level context information
- **Error Codes**: Organized code system by error layers
- **Error Conversion**: Multiple conversion strategies:
  ```rust
  .owe()           // Convert with specific reason
  .owe_validation() // Convert to validation error
  .owe_biz()       // Convert to business error
  .owe_sys()       // Mark as system error
  .err_conv()      // Automatic type conversion
  ```

## Installation

Add to Cargo.toml:
```toml
[dependencies]
orion-error = "0.3"
```

## Quick Start
## Core Concepts

### Error Definition
Define domain errors with enum and implement `DomainReason`:
```rust
#[derive(Debug, Display)]
enum OrderReason {
    InsufficientFunds,
    UserNotFound,
}

impl DomainReason for OrderReason {}
```

### Error Construction
Build error context with chaining:
```rust
validate_user(user_id)
    .want("Validate user")       // Add operation description
    .with_detail("uid:123")      // Add debug details
    .owe(OrderError::UserNotFound) // Convert to upper error type
```

### Error Handling
#### Conversion Strategies
| Method        | Description                      |
|---------------|----------------------------------|
| `.owe()`      | Convert to specific biz error    |
| `.owe_sys()`  | Mark as system error             |
| `.err_conv()` | Auto-detect error type conversion|

#### Handling Patterns
```rust
// Pattern 1: Direct conversion
parse_input().map_err(|e| e.owe(OrderError::ParseFailed))?;

// Pattern 2: Add context
db.query()
   .want("Read order data")
   .with_detail(format!("order_id={id}"))
   .err_conv()?;
```

## 与 thiserror 的差异与配合

- 定位差异:`thiserror` 专注于“定义错误类型”的派生与格式化;本库专注“结构化错误治理”,提供统一分类(`UvsReason`)、错误码(`ErrorCode`)、上下文(`OperationContext`/`WithContext`)与转换策略(`ErrorOwe`/`ErrorConv`)。
- 运行时语义:`thiserror` 不提供错误码、重试性或严重级别;本库内建 `error_code()``is_retryable()``is_high_severity()``category_name()`,便于监控与告警。
- 上下文与链路:`thiserror` 不管理上下文;本库可在成功/失败路径记录目标与键值上下文,`with_auto_log()` 结合日志在 Drop 时输出。
- 转换与传播:基于 `ErrorOwe` 将任意 `Result<T, E: Display>` 规范化为 `Result<T, StructError<R>>`,快速映射为业务/系统/网络/超时等分类。

推荐组合用法:用 `thiserror` 定义领域错误,用本库统一分类与治理。

```rust
use derive_more::From;
use thiserror::Error;
use orion_error::{StructError, ErrorOwe, ErrorCode, UvsReason, DomainReason};

#[derive(Debug, Error, From, serde::Serialize, PartialEq)]
enum AppError {
    #[error("{0}")]
    Uvs(UvsReason), // 透传统一分类
    #[error("parse failed")]
    Parse,
}

impl ErrorCode for AppError {
    fn error_code(&self) -> i32 {
        match self { AppError::Uvs(r) => r.error_code(), AppError::Parse => 100 }
    }
}
// 满足 From<UvsReason> + Display + PartialEq + Serialize,自动实现 DomainReason
impl DomainReason for AppError {}

fn handle() -> Result<(), StructError<AppError>> {
    do_io().owe_sys()?;        // 映射为系统类错误
    parse().owe_validation()?; // 映射为校验类错误
    Ok(())
}
```

更多内容与实践建议:参见 docs/thiserror-comparison.md。

## Advanced Features

### Error Composition
```rust
use orion_error::{UvsReason, StructError, ErrorWith, WithContext};

// Compose errors with rich context
fn complex_operation() -> Result<(), StructError<UvsReason>> {
    let mut ctx = WithContext::want("complex_operation");
    ctx.with("step", "validation");
    ctx.with("input_type", "user_request");

    // Validation error with context
    validate_input(&request)
        .want("input validation")
        .with(&ctx)?;

    ctx.with("step", "business_logic");

    // Business error with context
    check_business_rules(&request)
        .want("business rules check")
        .with(&ctx)?;

    ctx.with("step", "persistence");

    // System error with context
    save_to_database(&processed_data)
        .want("data persistence")
        .with(&ctx)?;

    Ok(())
}
```

### Error Propagation Strategies
```rust
use orion_error::{UvsReason, StructError, ErrorOwe};

// Different conversion strategies
fn process_with_strategies() -> Result<(), StructError<UvsReason>> {
    // Strategy 1: Convert to validation error
    let input = get_input().owe_validation()?;

    // Strategy 2: Convert to business error
    let validated = validate(input).owe_biz()?;

    // Strategy 3: Convert to system error
    let result = process(validated).owe_sys()?;

    // Strategy 4: Convert with custom reason
    let final_result = finalize(result).owe(UvsReason::business_error("finalization failed"))?;

    Ok(final_result)
}
```

### Error Recovery Patterns
```rust
use orion_error::UvsReason;

fn robust_operation() -> Result<(), MyError> {
    let mut attempts = 0;
    let max_attempts = 3;

    loop {
        attempts += 1;

        match attempt_operation() {
            Ok(result) => return Ok(result),
            Err(error) => {
                // Check if error is retryable and within attempt limit
                if error.is_retryable() && attempts < max_attempts {
                    log::warn!("Attempt {} failed, retrying: {}", attempts, error);
                    std::thread::sleep(std::time::Duration::from_secs(2));
                    continue;
                } else {
                    return Err(error.into());
                }
            }
        }
    }
}

// Fallback pattern
fn operation_with_fallback() -> Result<String, MyError> {
    // Try primary method
    primary_method().map_err(|e| {
        log::warn!("Primary method failed: {}", e);
        // Convert to business error with fallback context
        UvsReason::business_error("primary method unavailable, fallback not implemented")
    })
}
```

### Error Monitoring Integration
```rust
use orion_error::UvsReason;

// Integration with monitoring systems
struct ErrorMonitor;

impl ErrorMonitor {
    fn track_error(&self, error: &UvsReason) {
        // Send to monitoring system
        let event = MonitoringEvent {
            error_code: error.error_code(),
            category: error.category_name(),
            severity: if error.is_high_severity() { "high" } else { "normal" },
            retryable: error.is_retryable(),
            message: error.to_string(),
            timestamp: chrono::Utc::now(),
        };

        self.send_to_monitoring(event);
    }

    fn should_alert(&self, error: &UvsReason) -> bool {
        error.is_high_severity() ||
        error.error_code() >= 200 // Infrastructure layer errors
    }
}

// Usage in application
fn handle_api_error(error: UvsReason) -> HttpResponse {
    let monitor = ErrorMonitor::new();
    monitor.track_error(&error);

    if monitor.should_alert(&error) {
        alert_team(&error);
    }

    // Convert error to HTTP response based on category
    match error.category_name() {
        "validation" => HttpResponse::BadRequest().json(error.to_string()),
        "business" => HttpResponse::Conflict().json(error.to_string()),
        "not_found" => HttpResponse::NotFound().json(error.to_string()),
        "permission" => HttpResponse::Unauthorized().json(error.to_string()),
        "system" | "network" | "timeout" | "resource" => {
            HttpResponse::ServiceUnavailable().json(error.to_string())
        }
        _ => HttpResponse::InternalServerError().json(error.to_string()),
    }
}
```

## Migration Guide

### From Version 0.2 to 0.3

The error classification system has been significantly improved with a new hierarchical structure. Here's how to migrate:

#### **Error Type Changes**
```rust
// Old way (v0.2)
use orion_error::UvsReason;

let error = UvsReason::BizError("business logic failed".into());
let error = UvsReason::LogicError("logic error".into());
let error = UvsReason::Timeout("timeout occurred".into());

// New way (v0.3)
use orion_error::UvsReason;

let error = UvsReason::business_error("business logic failed");
let error = UvsReason::validation_error("logic error");
let error = UvsReason::timeout_error("timeout occurred");
```

#### **Trait Method Changes**
```rust
// Old way (v0.2)
let error = string_value.from_biz();
let error = string_value.from_logic();
let error = string_value.from_rule();

// New way (v0.3)
let error = UvsReason::from_biz(string_value);
let error = UvsReason::from_validation(string_value);
// Note: Rule errors have been removed, use ValidationError instead
```

#### **Error Code Changes**
Error codes have been reorganized by layers:
```rust
// Old codes
BizError -> 101
LogicError -> 100
Timeout -> 109

// New codes
ValidationError -> 100
BusinessError -> 101
NotFoundError -> 102
PermissionError -> 103
TimeoutError -> 204
```

#### **New Features Usage**
```rust
// Check retryability
if error.is_retryable() {
    // Implement retry logic
}

// Check severity
if error.is_high_severity() {
    // Send high priority alert
}

// Get category for metrics
let category = error.category_name();
```

## Full Example
See [examples/order_case.rs](examples/order_case.rs) for a comprehensive example showing all the new error classification features in action.

## Error Classification System

The `UvsReason` provides a comprehensive error classification system organized in three distinct layers:

### 🏗️ Error Layer Architecture

#### **Business Layer Errors (100-199)**
These are user-facing errors that are expected in normal application operation.

| Error Type | Code | Description | When to Use |
|------------|------|-------------|-------------|
| `ValidationError` | 100 | Input validation failures | Invalid parameters, format errors, constraint violations |
| `BusinessError` | 101 | Business logic violations | Rule violations, state conflicts, domain-specific errors |
| `NotFoundError` | 102 | Resource not found | Database record missing, file not found, user doesn't exist |
| `PermissionError` | 103 | Authorization failures | Access denied, authentication failed, insufficient permissions |

#### **Infrastructure Layer Errors (200-299)**
System-level failures that should be rare and often require operational attention.

| Error Type | Code | Description | When to Use |
|------------|------|-------------|-------------|
| `DataError` | 200 | Data processing errors | Database failures, data corruption, serialization errors |
| `SystemError` | 201 | OS and file system errors | Disk full, file permission issues, OS-level failures |
| `NetworkError` | 202 | Network connectivity errors | HTTP timeouts, connection failures, DNS resolution |
| `ResourceError` | 203 | Resource exhaustion | Memory full, CPU overload, connection pool exhausted |
| `TimeoutError` | 204 | Operation timeouts | Database query timeout, external service timeout |

#### **Configuration & External Layer Errors (300-399)**
Environment-related issues and third-party service failures.

| Error Type | Code | Description | When to Use |
|------------|------|-------------|-------------|
| `ConfigError` | 300 | Configuration issues | Missing config files, invalid configuration values |
| `ExternalError` | 301 | Third-party service errors | Payment gateway failures, external API failures |

## Error Classification
## Error Display
Built-in Display implementation shows full error chain:
```text
[Error Code 500] Insufficient funds
Caused by:
  0: User not found (code103)
     Detail: uid:456
     Context: "Validate funds"
  1: Storage full (code500)
     Context: "Save order"
```

## Contributing
Issues and PRs are welcome. Please follow existing code style.

## License
MIT License



---

# orion-error-zh <a name="orion-error-zh"></a>


用于构建大型应用程序的结构化错误处理库,提供完整的错误上下文追踪和灵活的归集策略

## 功能特性

- **结构化错误**:支持多层错误归集,保留完整错误链
- **错误分类**  - 业务错误(BizError) - 领域相关的可恢复错误
  - 系统错误(SysError) - 基础设施级别的严重错误
- **上下文追踪**:支持添加多级上下文信息
- **错误代码**:支持自定义错误代码体系
- **错误转换**:提供多种错误转换策略:
  ```rust
  .owe()      // 转换为业务错误
  .owe_sys()  // 转换为系统错误
  .err_conv() // 自动推导转换
  ```
  ## 安装

  在 Cargo.toml 中添加:
  ```toml
  [dependencies]
  orion-error = "0.2"
  ```



## 核心概念

### 错误定义
使用枚举定义领域错误类型,实现 `DomainReason` trait:
```rust
#[derive(Debug, Display)]
enum OrderReason {
    InsufficientFunds,
    UserNotFound,
}

impl DomainReason for OrderReason {}
```

### 错误构造
使用链式调用构建错误上下文:
```rust
validate_user(user_id)
    .want("验证用户")          // 添加操作描述
    .with_detail("uid:123")    // 添加调试细节
    .owe(OrderError::UserNotFound) // 转换为上层错误类型
```

### 错误处理
#### 转换策略
| 方法         | 说明                          |
|--------------|-----------------------------|
| `.owe()`     | 转换为指定业务错误,保留原始错误链   |
| `.owe_sys()` | 标记为系统级错误                |
| `.err_conv()`| 自动推导错误类型转换             |

#### 处理模式
```rust
// 模式1:直接转换
parse_input().map_err(|e| e.owe(OrderError::ParseFailed))?;

// 模式2:添加上下文
db.query()
   .want("读取订单数据")
   .with_detail(format!("order_id={id}"))
   .err_conv()?;
```
## 完整示例
见 [examples/order_case.rs](examples/order_case.rs)

## 错误展示
内置 Display 实现可展示完整错误链:
```text
[错误代码 500] 账户余额不足
Caused by:
  0: 用户不存在 (代码103)
     详情: uid:456
     上下文: "验证资金"
  1: 存储空间不足 (代码500)
     上下文: "保存订单"
```
## 贡献指南
欢迎提交 issue 和 PR,请遵循现有代码风格

## 许可证
MIT License