这个库提供了anyhow::Error,它是一个基于error类型的trait对象。可以方便的使用在Rust应用程序中。它可以方便的直接将anyhow::Result作为返回值就可以了,因为它直接实现了From where E: Error,所以就不需要再维护一个enum类型了,推荐只有在bin程序使用,在lib里面这么做的话,他人在使用的时候想特别处理某种情况的错误,只能通过downcast来处理。可以选择在lib里使用thiserror。
详情
使用Result,也可以简化为anyhow::Result,作为任何函数返回的类型。
在函数中,也可以使用?返回任何实现了std::error::Error的错误。
use anyhow::Result;
fn get_cluster_info() -> Result {
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 {
...
it.detach().context("Failed to detach the important thing")?;
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
Caused by:
No such file or directory (os error 2)
它支持向下转换,可以通过值、共享引用、可变的共享引用进行向下转换。
// If the error was caused by redaction, then return a
// tombstone instead of the content.
match root_cause.downcast_ref::() {
Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
None => Err(error),
}
anyhow可以和任何实现了std::error::Error的错误类型一起工作,包含你自定义的错误类型。它不包含derive(Error)宏,但是你可以通过thiserror库实现你自定义的错误。
use thiserror::Error;
#[derive(Error, Debug)]
pub enum FormatError {
#[error("Invalid header (expected {expected:?}, got {found:?})")]
InvalidHeader {
expected: String,
found: String,
},
#[error("Missing attribute: {0}")]
MissingAttribute(String),
}
一次性的错误可以通过anyhow!宏进行构造,支持字符串并生成anyhow::Error。
return Err(anyhow!("Missing attribute: {}", missing));
上面的错误还可以使用更简便的bail!宏。
bail!("Missing attribute: {}", missing);
只是简单的库介绍,更多内容请查看https://docs.rs/anyhow/1.0.71/anyhow/