error_in_core
#103765)Expand description
处理错误的接口。
Rust 中的错误处理
Rust 语言提供了两个互补的系统来构建、表示、报告、传播、响应和丢弃错误。
这些职责统称为 “error handling.” 第一个系统的组件,panic 运行时和接口,最常用于表示在您的程序中检测到的错误。
第二个系统的组件 Result
、错误 traits 和用户定义类型用于表示程序的预期运行时故障模式。
panic 接口
以下是 panic 系统的主要接口及其涵盖的职责:
panic!
和panic_any
(构造,自动传播)PanicInfo
(Reporting)set_hook
、take_hook
和#[panic_handler]
(Reporting)catch_unwind
和resume_unwind
(丢弃、传播)
以下是错误系统的主要接口及其涵盖的职责:
Result
(传播,反应)Error
trait (报告)- 用户定义类型 (构造 / 表示)
match
和downcast
(反应)- 问号运算符 (
?
) (传播) - 部分稳定的
Try
traits (传播, 构造) Termination
(Reporting)
将错误转化为 panic
panic 和错误系统并不完全不同。通常,API 中预期的运行时失败的错误可能会向调用者表示错误。
对于这些情况,标准库提供了 API 来构建以 Error
作为源的 panic。
这些函数是等价的,如果 Result
为 Ok
,则返回内部值; 如果 Result
为 Err
,则返回内部值,将内部错误打印为源。
它们之间的唯一区别是,对于 expect
,您提供了一个紧急错误消息以与源一起打印,而 unwrap
有一条默认消息,仅指示您打开了 Err
。
在这两者中,expect
通常是首选,因为它的 msg
字段允许您传达您的意图和假设,从而更容易追踪 panic 的来源。
另一方面,unwrap
仍然非常适合您可以简单地证明一段代码永远不会 panic 的情况,例如 "127.0.0.1".parse::<std::net::IpAddr>().unwrap()
或早期原型设计。
常见的消息样式
人们对表达 expect
信息有两种常见的方式。
使用消息向遇到 panic 的用户提供信息 (预期为错误消息
) 或使用该消息向调试 panic 的开发人员提供信息 (预期作为前提条件
)。
在前一种情况下,expect 消息用于描述已发生的错误,该错误被视为错误。考虑以下示例:
// Read environment variable, panic if it is not present
let path = std::env::var("IMPORTANT_PATH").unwrap();
Run在 “期望作为错误消息” 风格中,我们会使用 expect 来描述环境变量在应该设置的时候没有设置:
在 “期望作为前提条件” 风格中,我们将改为描述我们期望 Result
应该是 Ok
的原因。使用这种风格,我们更愿意写:
let path = std::env::var("IMPORTANT_PATH")
.expect("env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`");
Run“期望作为错误消息” 样式在 std panic 钩子的默认输出中效果不佳,并且通常会重复信息,这些信息已经被解包的源错误传达:
thread 'main' panicked at 'env variable `IMPORTANT_PATH` is not set: NotPresent', src/main.rs:4:6
在这个例子中,我们最终提到一个 env 变量没有设置,然后是我们的源消息说 env 不存在,我们传达的唯一附加信息是正在检查的环境变量的名称。
“期望作为前提条件” 风格反而专注于源代码的可读性,使得在使用 panic 专门表示错误的情况下更容易理解肯定出了什么问题。 此外,通过根据 “SHOULD” 发生什么来防止源错误来构建我们的期望,我们最终引入了独立于源错误的新信息。
thread 'main' panicked at 'env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`: NotPresent', src/main.rs:4:6
在这个例子中,我们不仅传达了应该设置的环境变量的名称,还解释了为什么应该设置它,并且我们让源错误显示为与我们的预期明显矛盾。
提示: 如果您无法记住如何表达期望作为前置条件样式的错误消息,请记住将注意力集中在 “should” 上,如 “env variable should be set by blah” 或 “the given binary should be available and executable by the current user” 中。