name: handling-rust-errors description: 使用error-stack crate的HASH错误处理模式。适用于处理Result类型、Report类型、定义自定义错误、使用change_context传播错误、使用attach添加上下文、实现Error trait或在Rust代码中记录错误条件。 license: AGPL-3.0 metadata: triggers: type: domain enforcement: suggest priority: high keywords: - 错误 - Result - Report - error-stack - change_context - attach - ResultExt intent-patterns: - “\b(处理|创建|定义|传播|转换)\b.?\b错误\b" - "\bReport<.>\b”
Rust错误处理模式
使用error-stack crate的HASH特定错误处理模式,以在整个Rust代码库中实现一致和可调试的错误处理。
核心原则
HASH独家使用error-stack进行错误处理:
✅ 做:
- 对所有错误类型使用
Report<MyError> - 使用具体错误类型:
Report<MyError> - 从
core::error::导入Error(而非std::error::) - 导入
ResultExt as _以使用trait方法
❌ 不做:
- 使用
anyhow或eyrecrate - 使用
Box<dyn Error>(测试或原型设计除外) - 使用
Report<Box<dyn Error>> - 使用
thiserror(使用derive_more替代)
HashQL编译器例外
HashQL编译器代码使用不同的错误处理方法。
位于libs/@local/hashql/*的代码使用hashql-diagnostics crate而非error-stack。这是因为编译器错误需要丰富的格式化功能:
- 指向精确代码位置的源范围
- 同一诊断中的多个标记区域
- 带有替换文本的修复建议
- 严重级别(错误、警告、提示)
使用方法:
| 位置 | 错误处理 |
|---|---|
libs/@local/hashql/*(编译器代码) |
使用hashql-diagnostics → 参见writing-hashql-diagnostics技能 |
| 其他所有地方 | 使用本技能中的error-stack模式 |
传统的error-stack模式仍适用于HashQL基础设施代码(CLI、文件I/O、配置),这些不涉及编译器诊断。
快速入门指南
选择与当前任务匹配的参考:
定义错误
当: 创建新错误类型或错误枚举时使用
- 使用
derive_more定义错误类型 - 错误枚举模式和变体
- 实现
Errortrait - 错误类型层次结构
传播错误
当: 处理Result类型、使用?操作符时使用
- 使用
.change_context()和.change_context_with()转换错误 - 使用
.attach()和.attach_with()添加上下文 - 错误转换模式
记录错误
当: 为可能失败的函数编写文档注释时使用
# 错误部分的格式- 链接错误变体
- 记录运行时错误
- 测试错误条件
常见快速模式
创建错误
use error_stack::Report;
return Err(Report::new(MyError::NotFound))
.attach(format!("ID: {}", id));
添加上下文传播错误
use error_stack::ResultExt as _;
some_result
.change_context(MyError::OperationFailed)
.attach("额外上下文")?;
惰性上下文(用于昂贵操作)
use error_stack::ResultExt as _;
expensive_operation()
.change_context(MyError::OperationFailed)
.attach_with(|| format!("调试信息: {:?}", expensive_computation()))?;