前言
错误处理在生产级别的代码中一直都是一个重点。在原型阶段,愉快地使用unwrap可以确保思路和精力被集中用在业务逻辑开发上。不过对于最终要上线的代码,优雅的处理错误却是至关重要的。原生Rust错误处理的工具有std::error::Error(一般我们会看到Box<dyn Error>的形式),?操作符以及enum供我们自定义错误类型。这本身就可以作为一个专题来讨论。而今天我们就来简单介绍一下failure库以及其背后的错误处理哲学。
简介
failure是rust-lang-nursery下的一个库,可以说是根正苗红的rust库了。其目标是取代基于std::eror::Error的错误处理。
failure有两个核心组件
Fail: 定制错误类型用的trait
Error: 只要实现了Fail,就能转化为该结构体
Fail trait
Fail trait被用来取代std::error::Error。它提供了backtrace和cause方法去获取错误的信息。也支持将错误包装在上下文(context)中。所有新的错误类型都应该实现该trait。对于一个实现了Fail的fail,我们可以逐层打印出错误链条
let mut fail: &Fail = err;
while let Some(cause) = fail.cause() {
println!("{}", cause);
fail = cause;
}
也可以打印出backtrace错误回溯
if let Some(bt) = err.cause().and_then(|cause| cause.backtrace()) {
println!("{}", bt)
}
也可以引入ResultExt从而给错误加入上下文(context)以分辨想通的错误。比如为了区分io错误,我们可以:
use failure::ResultExt;
let mut file = File::open(c