anyhow::Error trait(有点类似failure::Error)。而得益于std::error::Error所做的修改,它anyhow::Error是与std::error::Error兼容的。也就是说,对于自定义的错误类型,只需要实现std::error::Error即可。这对于程序的兼容性是一大利好,也因此failure库被日渐废弃。而thiserror正是方便大家为自定义的错误使用宏实现std::error::Error而设计的。[dependencies]anyhow = "1.0"thiserror = "1.0"Anyhow用法
Result<T, anyhow::Error>或者等价的anyhow::Result<T>,就可以利用?抛出任何类型实现了std::error::Error的错误use anyhow::Result;fn get_cluster_info() -> Result<ClusterMap> {let config = std::fs::read_to_string("cluster.json")?;let map: ClusterMap = serde_json::from_str(&config)?;Ok(map)}还可以给错误加上上下文(context)
use anyhow::{Context, Result};fn main() -> Result<()> {...let content = std::fs::read(path).with_context(|| format!("Failed to read instrs from {}", path))?;...}Error: Failed to read instrs from ./path/to/instrs.json这样就会在发送错误时看到上下文
Error: Failed to read instrs from ./path/to/instrs.jsonCaused by:No such file or directory (os error 2)anyhow宏可以基于错误字符串产生一个anyhow::Error(类似于failure中的format_err宏)
return Err(anyhow!("Missing attribute: {}", missing));thiserror用法
use thiserror::Error;#[derive(Error, Debug)]pub enum DataStoreError {#[error("data store disconnected")]Disconnect(#[from] io::Error),#[error("the data for key `{0}` is not available")]Redaction(String),#[error("invalid header (expected {expected:?}, found {found:?})")]InvalidHeader {expected: String,found: String,},#[error("unknown data store error")]Unknown,}实际上,只要为struct或者每个成员提供#[error("...")],那么就会实现Display,具体语法如下
#[error("{var}")] ⟶ write!("{}", self.var)#[error("{0}")] ⟶ write!("{}", self.0)#[error("{var:?}")] ⟶ write!("{:?}", self.var)#[error("{0:?}")] ⟶ write!("{:?}", self.0)source和backtrace字段(或者#[source]和#[backtrace])可以指定source()和backtrace()的返回。还可以通过#[from]实现为source实现From#[derive(Error, Debug)]pub enum MyError {Io {#[from]source: io::Error,backtrace: Backtrace,},}小结
std::error:Error,真香!原文作者:Rust语言中文社区;如有侵权,请联系管理员删除。