大型 Rust 项目的错误处理 - GreptimeDB 中的最佳实践

主要观点:讨论 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::Errorprovide方法重构栈跟踪工具等。
    关于 Greptime:提供时间序列数据库产品和解决方案,GreptimeDB 是开源高性能数据库,可通过 GreptimeCloud 试用,Edge-Cloud 集成方案优化 IoT 边缘场景,可在 GitHub 上 star 或加入 Slack 社区。
阅读 9
0 条评论