Install anyhow
masterTo use anyhow in your Rust project, add it to your Cargo.toml dependencies. By default, it enables the std feature.
[dependencies]
anyhow = "1.0"repository·master·Indexed 27 days ago
https://github.com/dtolnay/anyhowA flexible concrete Error type built on std::error::Error for Rust applications. It provides anyhow::Error and anyhow::Result to simplify error propagation and handling without defining custom error enums. Key features include the Context trait for adding human-readable information to errors, downcasting to underlying types, error chain iteration, and support for backtraces in Rust ≥ 1.65. It also supports no_std environments when the std feature is disabled and a global allocator is provided.
To use anyhow in your Rust project, add it to your Cargo.toml dependencies. By default, it enables the std feature.
[dependencies]
anyhow = "1.0"To use anyhow in a no_std environment, disable the default std feature in your Cargo.toml. Note that a global allocator is required.
Note for Rust < 1.81: You may need to manually call .map_err(Error::msg) when converting non-anyhow errors using ?, as the necessary trait for automatic conversion is only available in std for older Rust versions.
[dependencies]
anyhow = { version = "1.0", default-features = false }To use anyhow in a no_std environment, disable the default std feature in your Cargo.toml. Note that a global allocator is required.
[dependencies]
anyhow = { version = "1.0", default-features = false }Note for Rust < 1.81: In no_std mode, you may need to manually use .map_err(anyhow::Error::msg) when converting non-anyhow error types, as the ? operator's automatic conversion trait is only available in std for older Rust versions.
If you are using Rust $\ge$ 1.65, anyhow captures and prints a backtrace if the underlying error does not provide one. To see backtraces, you must enable them via environment variables:
RUST_BACKTRACE=1: Enables backtraces for both panics and errors.RUST_LIB_BACKTRACE=1: Enables backtraces for errors only.RUST_BACKTRACE=1 and RUST_LIB_BACKTRACE=0: Enables backtraces for panics only.Use the Context trait to add high-level information to low-level errors. This helps in troubleshooting by explaining what the application was doing when the error occurred. You can use .context() for static strings or .with_context(|| ...) for lazily evaluated strings (e.g., using format!).
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))?;
// ...
}You can attempt to downcast an anyhow::Error to a specific error type using downcast_ref, downcast_mut, or by value. This is useful when you need to inspect the underlying cause of an error.
// If the error was caused by redaction, then return a
// tombstone instead of the content.
match root_cause.downcast_ref::<DataStoreError>() {
Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
None => Err(error),
}anyhow! macro to construct an anyhow::Error with string interpolation. Use the bail! macro as a shorthand to return an error early from a function.Use anyhow::Result<T> (which is an alias for Result<T, anyhow::Error>) as the return type for fallible functions. You can use the ? operator to propagate any error that implements the std::error::Error trait.
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)
}If using Rust $\ge$ 1.65, anyhow captures a backtrace if the underlying error does not provide one. Control backtrace visibility using environment variables:
RUST_BACKTRACE=1: Enables backtraces for both panics and errors.RUST_LIB_BACKTRACE=1: Enables backtraces for errors only.RUST_BACKTRACE=1 and RUST_LIB_BACKTRACE=0: Enables backtraces for panics only.Use the context or with_context methods from the anyhow::Context trait to add human-readable information to errors. This helps identify where in the application logic a low-level error occurred.
context(msg): Takes a value that implements Display.with_context(|| msg): Takes a closure that returns a Display value, evaluating it lazily only if an error occurs.Use Error::chain() to get an iterator over the sequence of errors (the context and the underlying causes).
use anyhow::Error;
use std::io;
pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> {
for cause in error.chain() {
if let Some(io_error) = cause.downcast_ref::<io::Error>() {
return Some(io_error.kind());
}
}
None
}You can downcast an anyhow::Error to its underlying error type using downcast_ref, downcast_mut, or downcast. Because anyhow preserves the error chain, you can downcast to either the attached context type or the original underlying error type.
use anyhow::anyhow;
use std::fmt::{self, Display};
#[derive(Debug)]
enum DataStoreError {
Censored(()),
}
impl Display for DataStoreError {
fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
unimplemented!()
}
}
impl std::error::Error for DataStoreError {}
let error = anyhow!("...");
let root_cause = &error;
// Downcasting to the underlying error type
match root_cause.downcast_ref::<DataStoreError>() {
Some(DataStoreError::Censored(_)) => Ok(()),
None => Err(error),
}