Files
qiming/qiming-rcoder/.qoder/repowiki/zh/content/可观测性/错误处理.md
2026-06-01 13:54:52 +08:00

365 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 错误处理
<cite>
**本文档中引用的文件**
- [app_error.rs](file://crates/shared_types/src/model/app_error.rs)
- [http_result.rs](file://crates/shared_types/src/model/http_result.rs)
- [tracing_middleware.rs](file://crates/agent_runner/src/middleware/tracing_middleware.rs)
- [tracing_middleware.rs](file://crates/rcoder/src/middleware/tracing_middleware.rs)
- [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs)
- [agent_cancel_handler.rs](file://crates/agent_runner/src/handler/agent_cancel_handler.rs)
- [lib.rs](file://crates/shared_types/src/lib.rs)
</cite>
## 目录
1. [简介](#简介)
2. [核心错误类型](#核心错误类型)
3. [HTTP中间件错误处理](#http中间件错误处理)
4. [应用级错误结构](#应用级错误结构)
5. [错误传播与日志记录](#错误传播与日志记录)
6. [错误分类与状态码映射](#错误分类与状态码映射)
7. [错误信息暴露策略](#错误信息暴露策略)
8. [可观测性集成](#可观测性集成)
9. [常见问题与解决方案](#常见问题与解决方案)
10. [错误处理流程图](#错误处理流程图)
11. [监控与告警最佳实践](#监控与告警最佳实践)
## 简介
本文档全面解释系统中的错误处理机制,重点描述在 `tracing_middleware_handler` 中如何捕获和处理HTTP中间件错误包括 `Result<Response, StatusCode>` 的返回模式。结合 `shared_types` 中的 `AppError` 模型,说明应用级错误的结构设计和序列化方式。文档包括来自实际代码库的具体示例,如中间件中错误的传播和日志记录,以及错误处理与可观测性的集成。
## 核心错误类型
系统采用分层错误处理架构,主要包含两种核心错误类型:`AppError``HttpResult``AppError` 作为应用级错误的统一抽象,封装了不同来源的错误,而 `HttpResult` 则是标准化的HTTP响应格式用于向客户端返回一致的错误信息。
```mermaid
classDiagram
class AppError {
+AnyhowError(anyhow : : Error)
+IoError(std : : io : : Error)
+Generic(String)
+generic(msg : impl Into<String>) AppError
+internal_server_error(msg : &str) AppError
+validation_error(msg : &str) AppError
}
class HttpResult~T~ {
+code : String
+message : String
+data : Option~T~
+tid : Option~String~
+success : bool
+success(data : T) HttpResult~T~
+error(code : &str, message : &str) HttpResult~T~
+internal_error(message : &str) HttpResult~T~
}
AppError --> "implements" axum : : response : : IntoResponse
HttpResult~T~ --> "implements" axum : : response : : IntoResponse
HttpResult~T~ --> "serializes to" JSON
```
**图源**
- [app_error.rs](file://crates/shared_types/src/model/app_error.rs#L3-L30)
- [http_result.rs](file://crates/shared_types/src/model/http_result.rs#L24-L58)
**本节源**
- [app_error.rs](file://crates/shared_types/src/model/app_error.rs#L1-L64)
- [http_result.rs](file://crates/shared_types/src/model/http_result.rs#L1-L103)
## HTTP中间件错误处理
`tracing_middleware_handler` 是系统中的核心HTTP中间件负责请求追踪和错误处理。该中间件采用 `Result<Response, StatusCode>` 的返回模式确保所有HTTP请求都能被正确处理或以适当的HTTP状态码返回错误。
中间件的主要功能包括:
1. 为每个HTTP请求自动生成 `trace_id`
2. 创建请求span用于日志跟踪
3. 记录请求和响应信息
4. 自动将 `trace_id` 注入到OpenTelemetry上下文中
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Middleware as "tracing_middleware_handler"
participant Next as "下一个处理器"
participant Response as "响应"
Client->>Middleware : HTTP请求
Middleware->>Middleware : 提取或生成trace_id
Middleware->>Middleware : 创建追踪span
Middleware->>Middleware : 记录请求开始日志
Middleware->>Next : 调用next.run()
Next-->>Middleware : 返回Response
Middleware->>Middleware : 记录响应完成日志
Middleware->>Response : 返回Result<Response, StatusCode>
Response-->>Client : HTTP响应
```
**图源**
- [tracing_middleware.rs](file://crates/agent_runner/src/middleware/tracing_middleware.rs#L72-L130)
- [tracing_middleware.rs](file://crates/rcoder/src/middleware/tracing_middleware.rs#L72-L130)
**本节源**
- [tracing_middleware.rs](file://crates/agent_runner/src/middleware/tracing_middleware.rs#L1-L179)
- [tracing_middleware.rs](file://crates/rcoder/src/middleware/tracing_middleware.rs#L1-L179)
## 应用级错误结构
`AppError` 枚举是系统中应用级错误的核心数据结构,定义了三种主要的错误类型:
1. **AnyhowError**: 包装 `anyhow::Error` 类型,用于处理任意错误
2. **IoError**: 包装标准库的 `std::io::Error`用于处理I/O操作错误
3. **Generic**: 通用错误类型,用于表示自定义错误消息
`AppError` 实现了 `axum::response::IntoResponse` trait使其可以直接作为HTTP响应返回。当错误发生时系统会根据错误类型映射到相应的HTTP状态码并生成结构化的JSON响应。
```mermaid
flowchart TD
Start([错误发生]) --> MatchError["匹配AppError类型"]
MatchError --> AnyhowError{"是AnyhowError?"}
AnyhowError --> |是| Set500["设置状态码500"]
MatchError --> IoError{"是IoError?"}
IoError --> |是| Set500
MatchError --> Generic{"是Generic?"}
Generic --> |是| Set500
Set500 --> CreateJSON["创建JSON响应体"]
CreateJSON --> ReturnResponse["返回Response"]
ReturnResponse --> End([错误响应完成])
```
**图源**
- [app_error.rs](file://crates/shared_types/src/model/app_error.rs#L33-L56)
**本节源**
- [app_error.rs](file://crates/shared_types/src/model/app_error.rs#L1-L64)
## 错误传播与日志记录
系统中的错误传播遵循Rust的错误处理最佳实践使用 `?` 操作符进行错误传播,并在适当的位置使用 `map_err` 进行错误转换。这种模式确保了错误信息能够在调用栈中正确传递,同时保持代码的简洁性。
在日志记录方面,系统使用 `tracing` 库进行结构化日志记录。每个错误都会被记录为包含 `trace_id` 的结构化日志条目,便于后续的错误追踪和分析。
```rust
// 示例:错误传播和日志记录
let project_workspace = get_project_workspace(&project_id).await?;
```
```rust
// 示例:错误转换
.map_err(|e| anyhow::anyhow!(e))?;
```
```rust
// 示例:错误日志记录
error!(
"❌ 收到 agent 执行结果失败: {}",
e
);
```
**本节源**
- [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L261-L261)
- [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L283-L283)
- [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L312-L316)
## 错误分类与状态码映射
系统采用统一的错误分类和状态码映射策略,确保错误处理的一致性。错误分类主要基于错误的严重程度和来源:
1. **客户端错误** (4xx): 由客户端请求引起的错误,如参数验证失败
2. **服务器错误** (5xx): 由服务器内部问题引起的错误,如数据库连接失败
3. **业务逻辑错误**: 特定于业务场景的错误,使用自定义错误码
状态码映射遵循HTTP标准同时使用自定义错误码提供更详细的错误信息。例如`5000` 表示内部服务器错误,`9010` 表示Agent正在执行任务等。
```mermaid
erDiagram
ERROR_CATEGORY {
string code PK
string name
string description
int http_status
string severity
}
ERROR_CODE {
string code PK
string category FK
string message
string solution
datetime created_at
}
ERROR_CATEGORY ||--o{ ERROR_CODE : contains
ERROR_CATEGORY {
"CLIENT_ERROR" "客户端错误" "请求参数错误等" 400 "HIGH"
"SERVER_ERROR" "服务器错误" "内部服务错误" 500 "CRITICAL"
"BUSINESS_ERROR" "业务错误" "业务逻辑错误" 400 "MEDIUM"
}
ERROR_CODE {
"0001" "BUSINESS_ERROR" "停止智能体执行失败" "重试或联系管理员" "2024-01-01"
"5000" "SERVER_ERROR" "内部服务器错误" "检查服务日志" "2024-01-01"
"9010" "BUSINESS_ERROR" "Agent正在执行任务" "等待当前任务完成" "2024-01-01"
"PROMPT001" "SERVER_ERROR" "Agent处理失败" "检查Agent状态" "2024-01-01"
}
```
**图源**
- [http_result.rs](file://crates/shared_types/src/model/http_result.rs#L56-L57)
- [agent_cancel_handler.rs](file://crates/agent_runner/src/handler/agent_cancel_handler.rs#L213-L213)
- [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L218-L218)
**本节源**
- [http_result.rs](file://crates/shared_types/src/model/http_result.rs#L46-L58)
- [agent_cancel_handler.rs](file://crates/agent_runner/src/handler/agent_cancel_handler.rs#L134-L138)
- [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L181-L184)
## 错误信息暴露策略
系统采用谨慎的错误信息暴露策略,平衡了调试需求和安全考虑。错误信息暴露遵循以下原则:
1. **生产环境最小化暴露**: 在生产环境中,只暴露必要的错误信息,避免泄露敏感信息
2. **开发环境详细暴露**: 在开发环境中,提供详细的错误信息,便于调试
3. **结构化错误响应**: 所有错误都以统一的JSON格式返回包含错误码、消息和trace_id
`HttpResult` 结构的设计体现了这一策略,它包含 `code``message``data``tid``success` 字段,确保客户端能够获得足够的信息来处理错误,同时不会暴露过多的内部细节。
```mermaid
stateDiagram-v2
[*] --> Production
[*] --> Development
Production --> ErrorHandling : 发生错误
Development --> ErrorHandling : 发生错误
ErrorHandling --> CheckEnvironment : 检查环境
CheckEnvironment --> |生产环境| MinimizeInfo : 最小化错误信息
CheckEnvironment --> |开发环境| DetailedInfo : 详细错误信息
MinimizeInfo --> FormatResponse : 格式化为标准响应
DetailedInfo --> FormatResponse : 格式化为标准响应
FormatResponse --> LogError : 记录完整错误日志
LogError --> ReturnResponse : 返回响应
ReturnResponse --> [*]
```
**图源**
- [http_result.rs](file://crates/shared_types/src/model/http_result.rs#L24-L33)
- [app_error.rs](file://crates/shared_types/src/model/app_error.rs#L33-L56)
**本节源**
- [http_result.rs](file://crates/shared_types/src/model/http_result.rs#L1-L103)
## 可观测性集成
错误处理与系统的可观测性深度集成,主要体现在以下几个方面:
1. **分布式追踪**: 每个请求都分配唯一的 `trace_id`,贯穿整个请求处理链路
2. **结构化日志**: 所有错误日志都包含 `trace_id`,便于跨服务追踪
3. **指标监控**: 错误发生时记录相应的指标,用于监控和告警
`trace_id` 的生成和传播机制确保了在复杂的微服务架构中,能够快速定位和诊断问题。系统优先从请求头中提取 `trace_id`如果不存在则生成新的UUID作为 `trace_id`
```mermaid
graph TD
A[客户端请求] --> B{包含trace_id?}
B --> |是| C[使用请求中的trace_id]
B --> |否| D[生成新的trace_id]
C --> E[注入到OpenTelemetry上下文]
D --> E
E --> F[记录带trace_id的日志]
F --> G[传播到下游服务]
G --> H[集中式日志系统]
H --> I[错误分析和根因定位]
```
**图源**
- [tracing_middleware.rs](file://crates/agent_runner/src/middleware/tracing_middleware.rs#L80-L83)
- [http_result.rs](file://crates/shared_types/src/model/http_result.rs#L9-L22)
- [http_result.rs](file://crates/shared_types/src/model/http_result.rs#L51-L51)
**本节源**
- [tracing_middleware.rs](file://crates/agent_runner/src/middleware/tracing_middleware.rs#L1-L179)
- [http_result.rs](file://crates/shared_types/src/model/http_result.rs#L1-L103)
## 常见问题与解决方案
在实际使用中,可能会遇到一些常见的错误处理问题,以下是这些问题及其解决方案:
### 错误信息泄露
**问题**: 生产环境中暴露了过多的内部错误细节,可能导致安全风险。
**解决方案**: 实现环境感知的错误响应策略,在生产环境中只返回通用的错误消息,详细的错误信息仅在开发环境中暴露。
### 错误码不一致
**问题**: 不同的处理器使用不同的错误码,导致客户端难以处理。
**解决方案**: 建立统一的错误码注册表,所有错误码都从中心化的位置获取,确保一致性。
### trace_id丢失
**问题**: 在某些异步操作中,`trace_id` 可能丢失,导致无法完整追踪请求链路。
**解决方案**: 在 `HttpResult``into_response` 实现中添加 `trace_id` 的补全逻辑,确保即使在中间件之外创建的响应也能包含 `trace_id`
```mermaid
flowchart TD
A[问题识别] --> B[错误信息泄露]
A --> C[错误码不一致]
A --> D[trace_id丢失]
B --> E[实施环境感知响应]
C --> F[建立错误码注册表]
D --> G[实现trace_id补全]
E --> H[解决方案]
F --> H
G --> H
H --> I[改进的错误处理]
```
**图源**
- [http_result.rs](file://crates/shared_types/src/model/http_result.rs#L82-L84)
- [app_error.rs](file://crates/shared_types/src/model/app_error.rs#L17-L29)
**本节源**
- [http_result.rs](file://crates/shared_types/src/model/http_result.rs#L78-L85)
- [app_error.rs](file://crates/shared_types/src/model/app_error.rs#L16-L30)
## 错误处理流程图
以下是系统错误处理的完整流程图,展示了从错误发生到最终响应的整个过程:
```mermaid
flowchart TD
A[HTTP请求] --> B[tracing_middleware]
B --> C[提取/生成trace_id]
C --> D[创建追踪span]
D --> E[调用业务处理器]
E --> F{发生错误?}
F --> |是| G[捕获错误]
F --> |否| H[返回成功响应]
G --> I[转换为AppError]
I --> J[记录错误日志]
J --> K[创建HttpResult错误响应]
K --> L[序列化为JSON]
L --> M[返回HTTP错误响应]
H --> N[创建HttpResult成功响应]
N --> O[序列化为JSON]
O --> P[返回HTTP成功响应]
M --> Q[客户端]
P --> Q
style F fill:#f9f,stroke:#333,stroke-width:2px
style G fill:#f96,stroke:#333,stroke-width:2px
style H fill:#6f9,stroke:#333,stroke-width:2px
```
**图源**
- [tracing_middleware.rs](file://crates/agent_runner/src/middleware/tracing_middleware.rs#L72-L130)
- [app_error.rs](file://crates/shared_types/src/model/app_error.rs#L33-L56)
- [http_result.rs](file://crates/shared_types/src/model/http_result.rs#L77-L102)
**本节源**
- [tracing_middleware.rs](file://crates/agent_runner/src/middleware/tracing_middleware.rs#L72-L130)
- [app_error.rs](file://crates/shared_types/src/model/app_error.rs#L33-L56)
- [http_result.rs](file://crates/shared_types/src/model/http_result.rs#L77-L102)
## 监控与告警最佳实践
为了有效监控和告警系统中的错误,建议采用以下最佳实践:
1. **基于trace_id的根因分析**: 利用 `trace_id` 作为关键字,在日志系统中搜索完整的请求链路,快速定位问题根源。
2. **错误率监控**: 监控不同错误码的发生频率,设置告警阈值。
3. **P99延迟监控**: 监控错误响应的P99延迟确保错误处理不会成为性能瓶颈。
4. **错误分类仪表板**: 创建按错误类型、服务、时间维度分类的仪表板,便于趋势分析。
通过这些实践,可以建立一个健壮的错误监控体系,及时发现和解决系统中的问题。
**本节源**
- [tracing_middleware.rs](file://crates/agent_runner/src/middleware/tracing_middleware.rs#L98-L103)
- [tracing_middleware.rs](file://crates/agent_runner/src/middleware/tracing_middleware.rs#L115-L122)