主要观点:讨论 Rust 在 GreptimeDB 中的错误处理实践及未来工作,包括构建更便宜准确的错误栈替代系统回溯、组织大型项目中的错误、以不同方案打印错误给日志和用户等;分享在复杂系统中组织Error
变体类型的经验,如选择snafu
crate 构建错误系统,介绍如何为用户提供更好理解的错误栈(包含根因、全上下文栈、用户视角等信息),以及捕获系统回溯检测错误发生的方式和虚拟用户栈的实现,还提到呈现错误给用户时应包含的信息和低开销二进制大小优势等。
关键信息:
- Rust 错误处理围绕
Result<T, E>
枚举,通常E
扩展std::error::Error
。 - 在 GreptimeDB 中,选择
snafu
crate 构建错误系统,利用#[stack_trace_debug]
宏实现错误栈。 - 良好的错误报告应包含根因、全上下文栈和用户视角信息,如 GreptimeDB 的错误日志格式。
- 捕获系统回溯成本高,会增加二进制大小和引入噪声,虚拟用户栈可避免这些问题。
- 呈现错误给用户时应注重简洁有用的信息,如
KIND - REASON ([EXTERNAL CAUSE])
格式。
重要细节: thiserror
主要用于库,anyhow
用于二进制,而 GreptimeDB 需为每个 crate 定义错误类型,snafu
结合两者优点。- 系统回溯包含大量无关内部栈,虚拟栈可避免,且在批量处理等复杂逻辑中更易理解。
StackError
trait 提供访问和打印错误的方法,#[stack_trace_debug]
宏实现相关功能。- 区分内部和外部错误时,通过命名和检测实现,
debug_fmt
方法用于渲染错误栈。 - 二进制大小方面,去除
Location
和#[snafu(display)]
对.rodata
和整体二进制大小影响很小。
未来工作包括使stack_trace_debug
宏更通用,考虑使用std::error::Error
的provide
方法重构栈跟踪工具等。
关于 Greptime:提供时间序列数据库产品和解决方案,GreptimeDB 是开源高性能数据库,可通过 GreptimeCloud 试用,Edge-Cloud 集成方案优化 IoT 边缘场景,可在 GitHub 上 star 或加入 Slack 社区。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。