### Recommended Cargo.toml for Libraries Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/configuration.md Example Cargo.toml for a library using anyhow optionally. This setup avoids requiring anyhow by default in libraries and defines a feature for convenient errors. ```toml [package] name = "my-library" version = "0.1.0" edition = "2021" [dependencies] # Don't require anyhow by default in libraries anyhow = { version = "1.0", optional = true } [dev-dependencies] anyhow = "1.0" [features] default = [] convenient-errors = ["anyhow"] ``` -------------------------------- ### Recommended Cargo.toml for Applications Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/configuration.md Example Cargo.toml for an application using anyhow. Includes common dependencies like serde and tokio. ```toml [package] name = "my-app" version = "0.1.0" edition = "2021" [dependencies] anyhow = "1.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" tokio = { version = "1.0", features = ["full"] } [dev-dependencies] thiserror = "2" ``` -------------------------------- ### No-std Example: Embedded Project Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/configuration.md Example of using anyhow in a no_std environment. Most anyhow functionality is available, but requires careful error handling and allocation management. ```rust #![no_std] extern crate alloc; use anyhow::Result; fn process_data(data: &[u8]) -> Result> { // Most anyhow functionality available let result = parse(data) .map_err(|e| anyhow::anyhow!("Parse failed: {}", e))?; Ok(result) } fn parse(data: &[u8]) -> Result> { Ok(alloc::vec::Vec::new()) } ``` -------------------------------- ### Anyhow Project File Dependencies Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/MANIFEST.md Illustrates the hierarchical structure of the Anyhow project's documentation files, starting from the README.md. ```markdown README.md (Start here) ├── getting-started.md (Quick start guide) │ ├── api-reference-error.md │ ├── api-reference-result-type.md │ ├── api-reference-context.md │ ├── api-reference-macros.md │ └── errors.md ├── INDEX.md (Quick reference) │ ├── api-reference-*.md (All API refs) │ ├── types.md │ ├── errors.md │ ├── configuration.md │ └── module-structure.md ├── configuration.md (Setup & deployment) ├── module-structure.md (Internal details) └── types.md (Type signatures) API Reference Documents: ├── api-reference-error.md ├── api-reference-result-type.md ├── api-reference-context.md ├── api-reference-chain.md └── api-reference-macros.md Supporting Documents: ├── types.md ├── errors.md ├── configuration.md └── module-structure.md ``` -------------------------------- ### Basic Usage in main() Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/getting-started.md Use anyhow::Result<()> for main functions to automatically print error chains on failure. This example reads a config file. ```rust use anyhow::Result; fn main() -> Result<()> { let data = std::fs::read_to_string("config.json")?; println!("Config: {}", data); Ok(()) } ``` -------------------------------- ### Chained Context for Application Initialization Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-context.md Demonstrates chaining multiple `.context()` calls to build a detailed error history. This example shows loading configuration and then initializing the application, with context added at each step. ```rust use anyhow::{Context, Result}; use std::fs; fn load_config(path: &str) -> Result { fs::read_to_string(path) .with_context(|| format!("Loading config from {}", path))?; Ok(String::new()) } fn initialize_app() -> Result<()> { let config = load_config("app.toml") .context("Failed to initialize application")?; Ok(()) } ``` -------------------------------- ### Migrate from `failure` crate to `anyhow` Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/getting-started.md Replace `failure::Error` with `anyhow::Result` for a more streamlined error handling experience. This example shows reading a file with context. ```rust // Old: failure crate // fn operation() -> Result {} // New: anyhow use anyhow::Result; fn operation() -> Result { std::fs::read_to_string("file.txt") .context("Cannot read file")?; Ok(String::new()) } ``` -------------------------------- ### Example Usage of format_err! Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-macros.md Demonstrates how to use the format_err! macro to create and return an error with a formatted message. Ensure you have the anyhow::Result type in scope. ```rust use anyhow::{format_err, Result}; fn example() -> Result<()> { Err(format_err!("this error was formatted")) } ``` -------------------------------- ### Lazy Context with Formatting for File Processing Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-context.md Illustrates using `.with_context()` for lazy evaluation of context messages, which is efficient when the context string formatting is expensive. This example adds context to a file reading operation. ```rust use anyhow::{Context, Result}; use std::path::Path; fn process_file(path: &Path) -> Result { let content = std::fs::read_to_string(path) .with_context(|| { format!("Cannot read file {}", path.display()) })?; Ok(content) } ``` -------------------------------- ### Access Error Backtrace Information Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/errors.md Get the captured stack trace for an error. Available when Rust >= 1.65 with RUST_LIB_BACKTRACE=1 or RUST_BACKTRACE=1. ```rust use anyhow::Error; fn print_backtrace(error: &Error) { println!("Backtrace:\n{}", error.backtrace()); } ``` -------------------------------- ### Using Error::msg with Stream Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-macros.md This example shows how to use Error::msg() as an alternative to macros when working with iterator combinators or streams. It maps stream errors to anyhow::Error. ```rust use anyhow::Error; use futures::stream::TryStreamExt; async fn process(stream: S) -> Result, Error> where S: futures::stream::Stream>, { stream .map_err(Error::msg) .try_collect() .await } ``` -------------------------------- ### Error Propagation with ? Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/getting-started.md Propagate errors from functions returning anyhow::Result using the '?' operator. This example processes a file and converts its content to uppercase. ```rust use anyhow::Result; fn process_file(path: &str) -> Result { let content = std::fs::read_to_string(path)?; let processed = content.to_uppercase(); Ok(processed) } ``` -------------------------------- ### Usage of Result with custom error type Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/types.md Example demonstrating the usage of the `Result` type alias with a custom error type specified. This allows for more specific error handling when needed. ```rust // Two parameters — custom error type fn custom() -> Result { ... } ``` -------------------------------- ### Usage of Result with default error type Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/types.md Example demonstrating the usage of the `Result` type alias when the error type is the default `anyhow::Error`. This is the most common way to use `Result` in anyhow. ```rust // Single parameter — error is anyhow::Error fn process() -> Result { ... } ``` -------------------------------- ### Get Exact Size of Error Chain Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-chain.md The ExactSizeIterator trait allows you to get the precise number of errors in the chain using the len() method. ```rust use anyhow::Error; fn count_errors(error: &Error) -> usize { error.chain().len() } ``` -------------------------------- ### Get the Root Cause of an Error Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/errors.md Find the original error in the chain. Useful for determining the base failure. ```rust use anyhow::Error; fn get_root_message(error: &Error) -> String { error.root_cause().to_string() } ``` -------------------------------- ### last() Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-chain.md Gets the last (root) error in the chain. This method returns the ultimate cause of the error, or None if the chain is empty. ```APIDOC ## last() ### Description Gets the last (root) error in the chain. ### Returns `Option<&'a (dyn StdError + 'static)>` — The root cause, or `None` for empty chain ### Example ```rust use anyhow::Error; fn get_root_cause(error: &Error) -> Option { error.chain().last().map(|e| e.to_string()) } ``` ``` -------------------------------- ### Enable No-std Mode Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/configuration.md Configure dependencies and build profiles for no-std environments. Ensure a global allocator is provided and consider aborting on panic. ```toml [dependencies] anyhow = { version = "1.0", default-features = false } [profile.dev] # May be needed for no_std panic = "abort" ``` -------------------------------- ### len() Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-chain.md Gets the exact number of errors in the chain. This method returns the total count of errors that form the error chain. ```APIDOC ## len() ### Description Gets the exact number of errors in the chain. ### Returns `usize` — The total number of errors in the chain ### Example ```rust use anyhow::Error; fn check_depth(error: &Error) { if error.chain().len() > 5 { println!("Deep error chain!"); } } ``` ``` -------------------------------- ### Main Entry Point with Anyhow Result Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/getting-started.md The main function serves as the entry point, returning a Result from anyhow to propagate errors. ```rust use anyhow::Result; fn main() -> Result<()> { run() } fn run() -> Result<()> { let config = load_config()?; process_data(config)?; Ok(()) } ``` -------------------------------- ### skip(n) Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-chain.md Skips the first `n` errors in the chain, allowing you to process errors starting from a specific point in the chain. ```APIDOC ## skip(n) ### Description Skips the first `n` errors in the chain. ### Parameters #### Path Parameters - **n** (usize) - Required - Number of errors to skip ### Example ```rust use anyhow::Error; fn skip_immediate_cause(error: &Error) { // Skip the immediate error, print its causes for cause in error.chain().skip(1) { println!("Cause: {}", cause); } } ``` ``` -------------------------------- ### Test Success and Failure with Anyhow Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/getting-started.md Demonstrates how to test functions returning anyhow::Result, covering both successful operations and expected error conditions. ```rust #[cfg(test)] mod tests { use super::*; use anyhow::Result; #[test] fn test_valid_input() -> Result<()> { let result = process_data("valid")?; assert_eq!(result, "VALID"); Ok(()) } #[test] fn test_invalid_input() { let result = process_data(""); assert!(result.is_err()); } } fn process_data(input: &str) -> Result { if input.is_empty() { return Err(anyhow::anyhow!("input cannot be empty")); } Ok(input.to_uppercase()) } ``` -------------------------------- ### Build Script Configuration Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/configuration.md Configure a build script for compile-time checks. This script probes for compiler capabilities and enables conditional features. ```toml [build-script] build = "build.rs" ``` -------------------------------- ### Configure docs.rs Metadata Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/configuration.md Configure documentation builds for docs.rs. This includes specifying build targets and rustdoc arguments for enhanced documentation features like source links and macro expansion visibility. ```toml [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] rustdoc-args = [ "--generate-link-to-definition", "--generate-macro-expansion", "--extern-html-root-url=core=https://doc.rust-lang.org", "--extern-html-root-url=alloc=https://doc.rust-lang.org", "--extern-html-root-url=std=https://doc.rust-lang.org", ] ``` -------------------------------- ### Access Error Backtrace Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-error.md Use `backtrace` to get a reference to the captured backtrace for an error. The backtrace is only meaningful if the `RUST_LIB_BACKTRACE` or `RUST_BACKTRACE` environment variables are set. ```rust #[cfg(feature = "std")] pub fn backtrace(&self) -> &Backtrace ``` ```rust use anyhow::Error; fn print_backtrace(error: &Error) { println!("{}", error.backtrace()); } ``` -------------------------------- ### Add Anyhow to Project Dependencies Source: https://github.com/dtolnay/anyhow/blob/master/README.md Include anyhow in your Cargo.toml file to use its error handling capabilities. ```toml [dependencies] anyhow = "1.0" ``` -------------------------------- ### Check Error Chain Length Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-chain.md Use `len()` to get the exact number of errors in the chain. This method is useful for understanding the depth of nested errors. ```rust use anyhow::Error; fn check_depth(error: &Error) { if error.chain().len() > 5 { println!("Deep error chain!"); } } ``` -------------------------------- ### Using Result in main() Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-result-type.md The recommended pattern for application entry points. Errors returned from main() are automatically printed with their cause chain and backtrace. ```rust use anyhow::Result; fn main() -> Result<()> { let config = std::fs::read_to_string("config.toml")?; println!("Config: {}", config); Ok(()) } ``` -------------------------------- ### Handle Specific Error Types with Context Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/getting-started.md Shows how to handle specific error kinds, like file not found, and add context to other errors using anyhow. Requires `anyhow` and `std::io`. ```rust use anyhow::{Result, Context}; use std::io; fn read_file(path: &str) -> Result { match std::fs::read_to_string(path) { Ok(content) => Ok(content), Err(e) if e.kind() == io::ErrorKind::NotFound => { // Handle file not found Ok("default content".to_string()) } Err(e) => { // Convert other errors Err(anyhow::Error::from(e) .context(format!("Cannot read {}", path))) } } } ``` -------------------------------- ### Downcast Error Mutably Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-error.md Use `downcast_mut` to attempt to get a mutable reference to an error if it matches the specified type. This allows in-place modification of the downcasted error. ```rust pub fn downcast_mut(&mut self) -> Option<&mut E> where E: Display + Debug + Send + Sync + 'static, ``` ```rust use anyhow::Error; use std::io; fn modify_io_error(error: &mut Error) { if let Some(io_error) = error.downcast_mut::() { // Modify io_error... } } ``` -------------------------------- ### Log Errors with Anyhow Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/getting-started.md Demonstrates how to log errors and their cause chain using anyhow's Result type. Ensure anyhow is added as a dependency. ```rust use anyhow::Result; fn main() -> Result<()> { match try_work() { Ok(value) => println!("Success: {}", value), Err(e) => { eprintln!("Error: {}", e); // Print cause chain e.chain().skip(1).for_each(|cause| { eprintln!("Caused by: {}", cause); }); } } Ok(()) } fn try_work() -> Result { std::fs::read_to_string("data.txt") .map_err(|e| anyhow::Error::from(e)) } ``` -------------------------------- ### Using anyhow::Result for Error Handling Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-result-type.md Demonstrates how to use `anyhow::Result` for error handling, including downcasting errors using `downcast_ref`. This is useful for applications and binaries where a unified error type is preferred. ```rust use anyhow::Result; fn example() -> Result<()> { let error = get_error()?; // Can downcast if let Some(io_err) = error.downcast_ref::() { println!("IO error: {}", io_err); } Ok(()) } fn get_error() -> Result<(), anyhow::Error> { Err(anyhow::anyhow!("oops")) } ``` -------------------------------- ### Get Root Cause of Error Chain Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-chain.md Use `last()` to retrieve the final error in the chain, which is often considered the root cause. Returns `None` if the chain is empty. ```rust use anyhow::Error; fn get_root_cause(error: &Error) -> Option { error.chain().last().map(|e| e.to_string()) } ``` -------------------------------- ### Filter Error Chain by Predicate Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-chain.md Use `filter()` with a closure to select errors that match a specific condition. This example filters for `io::Error` types within the chain. ```rust use anyhow::Error; use std::io; fn find_io_errors(error: &Error) { let io_errors = error.chain() .filter(|cause| cause.downcast_ref::().is_some()); for error in io_errors { println!("IO Error: {}", error); } } ``` -------------------------------- ### Enable No-std Support in Cargo.toml Source: https://github.com/dtolnay/anyhow/blob/master/README.md To use anyhow in a no_std environment, disable the default 'std' feature and ensure a global allocator is available. This configuration is necessary for environments without the standard library. ```toml [dependencies] anyhow = { version = "1.0", default-features = false } ``` -------------------------------- ### Enable Default std Feature for Anyhow Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/configuration.md This configuration enables the default 'std' feature for the anyhow crate, which integrates standard library features. It is the default behavior. ```toml [dependencies] anyhow = "1.0" # Default: std feature enabled ``` -------------------------------- ### Avoid Cloning Error Chains in Anyhow Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/getting-started.md Demonstrates how to iterate over an error chain using references to avoid cloning, and shows a less efficient approach that involves cloning. ```rust // Good: pass reference fn handle(error: &anyhow::Error) { for cause in error.chain() { process(cause); } } // Less good: clone if you need ownership fn take_ownership(error: anyhow::Error) { let causes: Vec<_> = error.chain() .map(|c| c.to_string()) .collect(); } ``` -------------------------------- ### Printing the Full Error Chain in Rust with Anyhow Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/configuration.md Utilize the alternate display format (`{:#}`) with `eprintln!` to print the complete error chain when handling errors with Anyhow. ```rust use anyhow::Result; fn main() -> Result<()> { match try_main() { Ok(()) => Ok(()), Err(e) => { eprintln!("{:#}", e); // Print with full chain Err(e) } } } fn try_main() -> Result<()> { Ok(()) } ``` -------------------------------- ### Selective Clippy Lints Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/configuration.md Apply selective clippy lints to balance code style with practical needs. This configuration allows doc examples with backticks and permits glob imports where convenient. ```rust #![allow( clippy::doc_markdown, clippy::elidable_lifetime_names, clippy::enum_glob_use, // ... many more )] ``` -------------------------------- ### Error Handling with Formatted String Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-macros.md Demonstrates using `anyhow!` within a function to return an error with a formatted message, including input validation. ```rust use anyhow::{anyhow, Result}; fn lookup(key: &str) -> Result { if key.len() != 16 { return Err(anyhow!("key length must be 16 characters, got {:?}", key)); } Ok(String::from("value")) } ``` -------------------------------- ### Chain Iterator Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/types.md The Chain struct provides an iterator over the cause chain of an error, starting from the error itself and following the source() chain. It is generic over a lifetime parameter 'a representing the lifetime of the error chain. ```APIDOC ## Chain An iterator over the cause chain of an error, starting from the error itself and following the `source()` chain. **Generic Parameters:** | Parameter | Bounds | Description | |-----------|--------|-------------| | `'a` | Lifetime | The lifetime of the error chain | **Trait Implementations:** - `Iterator` - `DoubleEndedIterator` - `ExactSizeIterator` - `Clone` **Fields:** | Field | Type | Visibility | Description | |-------|------|------------|-------------| | `state` | `ChainState<'a>` | Private | The internal iteration state | ``` -------------------------------- ### Enable RUST_LIB_BACKTRACE Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/configuration.md Set RUST_LIB_BACKTRACE to 1 to capture backtraces in errors. This is a library-level setting. ```bash RUST_LIB_BACKTRACE=1 # Capture backtraces in errors RUST_LIB_BACKTRACE=0 # Disable backtrace capture ``` ```bash RUST_LIB_BACKTRACE=1 ./my_app ``` -------------------------------- ### Create Error from Formatted String Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-macros.md Use `anyhow!` with a format string and arguments to create a detailed error message, useful for including variable values. ```rust use anyhow::{anyhow, Result}; fn example2() -> Result { let value = 42; // Format string Err(anyhow!("expected number, got {}", value))?; Ok(String::new()) } ``` -------------------------------- ### Handle File I/O Errors Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/errors.md Process a file and handle potential I/O errors like FileNotFound or PermissionDenied using anyhow's Context. ```rust use anyhow::{Context, Result}; use std::fs; fn process_file(path: &str) -> Result { fs::read_to_string(path) .with_context(|| format!("Cannot read {}", path))?; Ok(String::new()) } ``` -------------------------------- ### Enable backtrace Feature for Anyhow Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/configuration.md This configuration enables the 'backtrace' feature for the anyhow crate. On modern Rust versions (>= 1.65), this feature is a no-op as it uses the standard library's backtrace functionality automatically. It is preserved for backward compatibility. ```toml [dependencies] anyhow = { version = "1.0", features = ["backtrace"] } ``` -------------------------------- ### Anyhow Ok() Helper for Type Inference Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-result-type.md Illustrates the use of the `anyhow::Ok()` helper function to resolve type inference issues when creating a `Result`. This function is particularly helpful in contexts where the compiler cannot automatically determine the error type `E`. ```rust pub fn Ok(value: T) -> Result { Result::Ok(value) } ``` ```rust use anyhow::{Ok, Result}; fn infer_type() { // This works: let _result: Result = Ok(1); // Without the function, this would fail: // let _result = Result::Ok(1); // Error: E cannot be inferred } ``` -------------------------------- ### Migrate from `Box` to `anyhow` Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/getting-started.md Simplify error handling by replacing `Box` with `anyhow::Result`. This change reduces boilerplate and improves type safety. ```rust // Old fn operation() -> Result> { Ok(String::new()) } // New use anyhow::Result; fn operation() -> Result { Ok(String::new()) } ``` -------------------------------- ### Create Error from String Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/getting-started.md Create a new anyhow::Error from a simple string literal. Use this for straightforward error messages. ```rust use anyhow::{anyhow, Result}; fn validate() -> Result<()> { Err(anyhow!("validation failed")) } ``` -------------------------------- ### Use Lazy Context for Expensive Computations in Anyhow Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/getting-started.md Illustrates the difference between eager and lazy context computation when adding context to errors, emphasizing that lazy computation avoids unnecessary work. ```rust // Lazy: only computed on error operation() .with_context(|| compute_expensive_context())?; // Not lazy: always computed operation() .context(compute_expensive_context())?; ``` -------------------------------- ### Option Context for Finding User ID Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-context.md Shows how to use `.context()` with an `Option` to provide a specific error message when a value is not found, such as a user in a collection. ```rust use anyhow::{Context, Result}; fn find_user_id(name: &str) -> Result { let users = vec![("alice", 1), ("bob", 2)]; let (_, id) = users.iter() .find(|(user_name, _)| user_name == &name) .context(format!("User {} not found", name))?; Ok(*id) } ``` -------------------------------- ### anyhow! Macro Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/INDEX.md Creates errors from strings, format strings, or existing errors. It's a versatile macro for generating anyhow::Error types. ```APIDOC ## anyhow! Macro ### Description Creates errors from strings, format strings, or existing errors. ### Usage ```rust anyhow!("literal message") anyhow!("format {}", value) anyhow!(existing_error) ``` ``` -------------------------------- ### Minimize String Allocations in Anyhow Errors Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/getting-started.md Compares creating an error with a literal string versus formatting a string, highlighting the performance benefit of avoiding unnecessary allocations. ```rust // Good: literal strings, no allocation return Err(anyhow!("validation failed")); // Less good: always allocates let msg = format!("validation failed"); return Err(anyhow!("{}", msg)); ``` -------------------------------- ### Enable RUST_BACKTRACE Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/configuration.md Set RUST_BACKTRACE to 1 to capture backtraces in both errors and panics. This setting takes precedence over RUST_LIB_BACKTRACE for errors. ```bash RUST_BACKTRACE=1 # Capture backtraces in both errors and panics ``` -------------------------------- ### Default Error Handling in main() Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-result-type.md Returning anyhow::Result<()> from main() enables automatic error catching, printing with Debug representation, including the cause chain and backtrace, and exiting with status code 1. This is ideal for CLI applications. ```rust fn main() -> anyhow::Result<()> { // Your code here Ok(()) } ``` -------------------------------- ### anyhow! Macro Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-macros.md Constructs an ad-hoc error from a string or existing error value. It supports literal strings, formatted strings with arguments, or any value implementing Debug and Display. ```APIDOC ## anyhow! Macro ### Description Constructs an ad-hoc error from a string or existing error value. It supports literal strings, formatted strings with arguments, or any value implementing Debug and Display. ### Signature Variants: | Pattern | Usage | Returns | |---|---|---| | `anyhow!("message")` | Literal string | `anyhow::Error` | | `anyhow!("format {}", var)` | Format string with arguments | `anyhow::Error` | | `anyhow!(expr)` | Any error or value implementing `Debug` and `Display` | `anyhow::Error` | ### Returns `anyhow::Error` — A new error object ### Details The macro accepts a format string with arguments, a literal string (becomes downcastable to `&'static str`), or any value implementing both `Debug` and `Display`. If passed a single argument implementing `std::error::Error`, the error's cause chain is preserved. ### Examples ```rust use anyhow::{anyhow, Result}; fn example1() -> Result<()> { // String literal Err(anyhow!("invalid input"))?; Ok(()) } fn example2() -> Result { let value = 42; // Format string Err(anyhow!("expected number, got {}", value))?; Ok(String::new()) } fn example3() -> Result<()> { use std::io; // Existing error with preserved cause chain let io_error = io::Error::last_os_error(); Err(anyhow!(io_error))?; Ok(()) } fn example4() -> Result<()> { use thiserror::Error; #[derive(Error, Debug)] #[error("parse error")] struct ParseError; // Any error type Err(anyhow!(ParseError))?; Ok(()) } fn lookup(key: &str) -> Result { if key.len() != 16 { return Err(anyhow!("key length must be 16 characters, got {:?}", key)); } Ok(String::from("value")) } ``` ``` -------------------------------- ### Configuring Backtrace Verbosity with Environment Variables Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/configuration.md Control the level of detail in backtraces using the `RUST_LIB_BACKTRACE` environment variable. Set `RUST_BACKTRACE` to include backtraces in panics. ```bash # Minimal backtrace RUST_LIB_BACKTRACE=1 ./app # Full backtrace with all frames RUST_LIB_BACKTRACE=full ./app # Include backtrace in panics too RUST_BACKTRACE=full ./app ``` -------------------------------- ### context Method Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-context.md Wraps an error with a static context message. For Result, it converts errors to anyhow::Error and attaches context. For Option, it converts None to an anyhow::Error with the provided context. ```APIDOC ## context Method ### Description Wraps an error with a static context message. ### Method `context(self, context: C) -> Result` ### Parameters #### Path Parameters - None #### Query Parameters - None #### Request Body - None ### Request Example ```rust use anyhow::{Context, Result}; use std::fs; use std::path::PathBuf; fn read_config(path: PathBuf) -> Result { fs::read_to_string(&path) .context("Failed to read configuration file")?; Ok(String::from("config")) } fn find_port() -> Result { let config = read_config("app.toml")?; config.parse().context("Port must be a valid number")?; Ok(8080) } ``` ### Response #### Success Response (200) - `Ok(T)`: Original Ok value. #### Error Response - `Err(Error)`: Original error wrapped with context, or a new error if the original type was Option::None. #### Response Example - For Result: `Ok(T)` or `Err(Error)` - For Option: `Ok(T)` or `Err(Error)` ``` -------------------------------- ### Display Formatting Options Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-error.md Details the different display formatting specifiers for the anyhow Error type, including how to show the cause chain and debug information. ```APIDOC ## Display Formatting The display representation of `Error` varies based on the format specifier: - `"{}"` — Displays only the outermost error message. - `"{:#}"` — Displays the outermost error message followed by the entire cause chain. - `"{:#?}"` — Displays structured debug format. - `"{:#?}"` — Displays the full debug representation with backtrace (if available). ``` -------------------------------- ### Migrate from failure crate to anyhow Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/INDEX.md Update function signatures to use anyhow's Result type instead of the failure crate's Error type for simpler error handling. ```rust // Old fn op() -> Result { } // New fn op() -> Result { } // anyhow::Result ``` -------------------------------- ### High-Level Operations with Context Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/getting-started.md Functions for loading configuration and processing data, using anyhow's Context trait to add contextual information to errors. ```rust use anyhow::{Context, Result}; fn load_config() -> Result { let path = "config.toml"; let text = std::fs::read_to_string(path) .with_context(|| format!("Cannot read {}", path))?; parse_config(&text) .context("Invalid configuration format") } fn process_data(config: Config) -> Result<()> { for item in &config.items { process_item(item) .context(format!("Error processing item '{}'", item))?; } Ok(()) } ``` -------------------------------- ### Basic Error Context with Result Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-context.md Demonstrates adding context to a `Result` using the `.context()` method. This is useful when an operation like reading a file might fail. ```rust use anyhow::{Context, Result}; use std::fs; fn main() -> Result<()> { let data = fs::read_to_string("config.json") .context("Failed to read config.json")?; Ok(()) } ``` -------------------------------- ### Debug Format with Backtrace Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/errors.md Employ the debug format (`{:?}`) to display structured error information, including a backtrace if available. This requires the `RUST_BACKTRACE=1` or `RUST_LIB_BACKTRACE=1` environment variable to be set. ```rust let error = anyhow::anyhow!("something failed"); println!("{:?}", error); // Prints with backtrace if available ``` -------------------------------- ### Context for Option Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-context.md Implements `Context` for `Option`, treating `None` as a failure case. ```rust impl Context for Option ``` -------------------------------- ### Create One-off Errors with anyhow! Macro Source: https://github.com/dtolnay/anyhow/blob/master/README.md Use the `anyhow!` macro to construct `anyhow::Error` instances with string interpolation for simple, one-off error messages. ```rust return Err(anyhow!("Missing attribute: {}", missing)); ``` -------------------------------- ### Create Ad-Hoc Errors with anyhow! Macro Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/errors.md Use the `anyhow!` macro to create errors from simple strings or formatted strings. This is ideal for custom error messages that don't require a specific error type. ```rust use anyhow::anyhow; fn example() -> Result<(), anyhow::Error> { if condition { Err(anyhow!("condition failed"))?; } Err(anyhow!("value was {}", some_var))?; Ok(()) } ``` -------------------------------- ### Create Error from Existing Error Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-macros.md Pass an existing error value to `anyhow!` to wrap it, preserving the original error's cause chain. ```rust use anyhow::{anyhow, Result}; use std::io; fn example3() -> Result<()> { // Existing error with preserved cause chain let io_error = io::Error::last_os_error(); Err(anyhow!(io_error))?; Ok(()) } ``` -------------------------------- ### Handling Specific Errors with Downcasting Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/INDEX.md Illustrates how to handle specific error types, such as `io::Error`, by downcasting a boxed error. This allows for specialized error recovery logic based on the underlying error kind. ```rust use anyhow::Result; use std::io; fn handle(path: &str) -> Result { if let Some(io_err) = read_file(path) .unwrap_err() .downcast_ref::() { println!("IO error: {:?}", io_err.kind()); } Ok(String::new()) } fn read_file(path: &str) -> Result { std::fs::read_to_string(path) .map_err(Into::into) } ``` -------------------------------- ### Low-Level Operations with Ensure and Context Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/getting-started.md Functions for processing individual items, using anyhow's ensure macro for validation and Context for error details. ```rust use anyhow::{ensure, Context, Result}; fn process_item(item: &str) -> Result<()> { ensure!(!item.is_empty(), "item cannot be empty"); let value = parse_value(item) .context("Cannot parse item value")?; validate_value(value)?; Ok(()) } fn parse_value(item: &str) -> Result { item.parse::() .context("Item must be a valid integer") } fn validate_value(value: i32) -> Result<()> { ensure!(value > 0, "Value must be positive"); Ok(()) } ``` -------------------------------- ### Set Minimum Supported Rust Version Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/configuration.md Specify the minimum Rust version required for your project in Cargo.toml. Anyhow requires Rust 1.68 or later. ```toml [package] rust-version = "1.68" ``` -------------------------------- ### bail! Macro Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/INDEX.md Provides a convenient way to perform an early return with an error from a function that returns a Result. ```APIDOC ## bail! Macro ### Description Early return with error. ### Usage ```rust bail!("error message") bail!("format {}", value) bail!(error_value) ``` ``` -------------------------------- ### Handle Network Request Errors Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/errors.md Fetch data from a URL and handle potential network errors like connection timeouts or HTTP errors using anyhow's Context. ```rust use anyhow::{Context, Result}; async fn fetch_url(url: &str) -> Result { reqwest::get(url).await .context("HTTP request failed")?; .text().await .context("Failed to read response") } ``` -------------------------------- ### Create Error from Custom Error Type Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-macros.md Any type implementing `Debug` and `Display` can be passed to `anyhow!` to create a new error. ```rust use anyhow::{anyhow, Result}; use thiserror::Error; #[derive(Error, Debug)] #[error("parse error")] struct ParseError; fn example4() -> Result<()> { // Any error type Err(anyhow!(ParseError))?; Ok(()) } ``` -------------------------------- ### anyhow! Macro Signature Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-macros.md The `anyhow!` macro constructs ad-hoc errors from string literals, formatted strings, or existing error values. It preserves the cause chain when given an existing error. ```rust #[macro_export] macro_rules! anyhow { ($msg:literal) => { ... }; ($err:expr) => { ... }; ($fmt:expr, $($arg:tt)*) => { ... }; } ``` -------------------------------- ### Display Immediate Error Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/errors.md Use the standard display format to show only the immediate error message without its cause chain. ```rust let error = anyhow::anyhow!("something failed"); println!("{}", error); // Prints: "something failed" ``` -------------------------------- ### Iterate Over Error Causes in Rust Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/INDEX.md Shows how to iterate over the chain of error causes using the `chain()` method on an `anyhow::Error` object. Useful for debugging. ```rust for cause in error.chain() { println!("Cause: {}", cause); } ``` -------------------------------- ### Debug for Error Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-error.md Displays the error with backtrace and cause chain formatted nicely when using the `{:?}` specifier. ```APIDOC ## Debug for Error ### Description Displays the error with backtrace and cause chain formatted nicely when using the `{:?}` specifier. ### Formatting - `{:?}`: Displays the full debug representation with backtrace (if available). ``` -------------------------------- ### Basic Error Propagation with Result Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/INDEX.md Demonstrates basic error propagation using Rust's Result type and the `?` operator. This pattern is common for handling fallible operations sequentially. ```rust use anyhow::Result; fn process() -> Result { let data = std::fs::read_to_string("file.txt")?; Ok(data) } ``` -------------------------------- ### Simplify Error Types for Applications Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/getting-started.md For most applications, use `anyhow::Result` for simple error handling with context. Custom error enums are typically only necessary for libraries with complex, specific error handling requirements. ```rust // Good for applications: simple errors with context fn app() -> Result<()> { operation().context("Something went wrong")?; Ok(()) } // Only necessary for libraries with specific error handling needs #[derive(Error, Debug)] enum LibError { #[error("...")] Specific, } ``` -------------------------------- ### Create Errors with anyhow! Macro Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/INDEX.md Use anyhow! to create errors from literal strings, formatted strings, or existing error types. This macro is versatile for generating various error conditions. ```rust anyhow!("literal message") ``` ```rust anyhow!("format {}", value) ``` ```rust anyhow!(existing_error) ``` -------------------------------- ### take(n) Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-chain.md Takes only the first `n` errors from the chain, useful for limiting the number of errors processed. ```APIDOC ## take(n) ### Description Takes only the first `n` errors from the chain. ### Parameters #### Path Parameters - **n** (usize) - Required - Maximum number of errors to take ### Example ```rust use anyhow::Error; fn print_first_three_causes(error: &Error) { for cause in error.chain().take(3) { println!("{}", cause); } } ``` ``` -------------------------------- ### Attaching Context to Errors Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-context.md Demonstrates how to attach custom context to an existing error using the `context` method. This allows for richer error information that can be downcast later. ```rust use anyhow::{Context, Result}; use std::io; #[derive(Debug)] struct NetworkError; impl std::fmt::Display for NetworkError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "network error") } } impl std::error::Error for NetworkError {} fn main() -> Result<()> { let io_err: io::Error = io::Error::last_os_error(); let error = io_err .context(NetworkError)?; Err(error) } ``` -------------------------------- ### Error::new Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-error.md Creates a new `anyhow::Error` from any type that implements `std::error::Error`. If the underlying error does not provide a backtrace, one will be automatically captured. The cause chain of the original error is preserved. ```APIDOC ## Error::new ### Description Creates a new error object from any error type that implements `std::error::Error`. ### Signature ```rust pub fn new(error: E) -> Self where E: StdError + Send + Sync + 'static, ``` ### Parameters #### Path Parameters - **error** (E) - Required - An error type implementing `std::error::Error` ### Returns `Error` — A new error object wrapping the input error with optional backtrace ### Details If the error type does not provide a backtrace, one will be automatically captured. The underlying error's cause chain is preserved. ### Example ```rust use anyhow::Error; use std::fs; fn example() -> Result { let content = fs::read_to_string("file.txt") .map_err(|e| Error::new(e))?; Ok(content) } ``` ``` -------------------------------- ### Using Result in Async Functions Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-result-type.md Works seamlessly with async code. This allows asynchronous operations to return Results, integrating smoothly with async error handling patterns. ```rust use anyhow::Result; async fn fetch_data(url: &str) -> Result { let response = reqwest::get(url).await?; let body = response.text().await?; Ok(body) } ``` -------------------------------- ### Early Return with bail! Macro Source: https://github.com/dtolnay/anyhow/blob/master/README.md The `bail!` macro provides a shorthand for returning an `anyhow::Error` from a function, simplifying the creation of errors for early exits. ```rust bail!("Missing attribute: {}", missing); ``` -------------------------------- ### bail! Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-macros.md Returns early with an error, equivalent to `return Err(anyhow!(...))`. The function must return `Result<_, anyhow::Error>`. The macro creates an error using the same rules as `anyhow!()` and immediately returns it. ```APIDOC ## bail! Returns early with an error, equivalent to `return Err(anyhow!(...))`. **Signature Variants:** | Pattern | Usage | |---|---| | `bail!("message")` | Literal string | | `bail!("format {}", var)` | Format string with arguments | | `bail!(expr)` | Any value implementing `Debug` and `Display` | **Returns:** Never returns; exits the enclosing function with `Err` **Details:** The function must return `Result<_, anyhow::Error>`. The macro creates an error using the same rules as `anyhow!()` and immediately returns it. **Examples:** ```rust use anyhow::{bail, Result}; fn validate_permission(user: usize, resource: usize) -> Result<()> { const ALLOWED_USER: usize = 0; if user != ALLOWED_USER { bail!("permission denied for accessing {}", resource); } Ok(()) } fn main() -> Result<()> { validate_permission(1, 100)?; Ok(()) } ``` ```rust use anyhow::{bail, Result}; use thiserror::Error; #[derive(Error, Debug)] enum ScienceError { #[error("recursion limit exceeded")] RecursionLimitExceeded, } const MAX_DEPTH: usize = 1; fn recurse(depth: usize) -> Result<()> { if depth > MAX_DEPTH { bail!(ScienceError::RecursionLimitExceeded); } Ok(()) } ``` ``` -------------------------------- ### format_err! Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-macros.md Alias for anyhow! macro, used to create an error from a format string. It is provided for backward compatibility with the failure crate. ```APIDOC ## format_err! Alias for `anyhow!()`. Creates an error from a format string, equivalent to `anyhow!()`. Provided for backward compatibility with the `failure` crate. **Example:** ```rust use anyhow::{format_err, Result}; fn example() -> Result<()> { Err(format_err!("this error was formatted")) } ``` ``` -------------------------------- ### Error::into_boxed_dyn_error Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-error.md Converts the Anyhow Error into a standard library error trait object, preserving backtrace if available. ```APIDOC ## Error::into_boxed_dyn_error ### Description Converts to a standard library error trait object. ### Method Signature ```rust pub fn into_boxed_dyn_error( self ) -> Box ``` ### Returns - **Box** — A boxed standard error ### Details This is a cheap pointer cast that does not allocate or deallocate memory. If a backtrace was captured, it remains accessible via the standard library's `Error` provider API, but the result can no longer be downcast to the original underlying type. ### Example ```rust use anyhow::Error; use std::error::Error; fn get_std_error(error: Error) -> Box { error.into_boxed_dyn_error() } ``` ``` -------------------------------- ### Add Context in Layers Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/getting-started.md Provide specific context at each layer of your application to make debugging easier. Avoid generic error messages that obscure the source of the failure. ```rust // Bad: user doesn't know what failed fn layer1() -> Result { layer2()?; Ok(Data) } fn layer2() -> Result<()> { layer3()?; Ok(()) } // Good: context at each layer fn layer1() -> Result { layer2().context("Layer 1 failed")?; Ok(Data) } fn layer2() -> Result<()> { layer3().context("Layer 2 failed")?; Ok(()) } ``` -------------------------------- ### Clone Anyhow Error Chain Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/api-reference-chain.md Demonstrates cloning an `anyhow::Error` chain. The `Chain` type implements `Clone`, allowing it to be duplicated for separate iteration or processing. ```rust use anyhow::Error; fn use_chain_twice(error: &Error) { let chain = error.chain(); let chain_copy = chain.clone(); // Iterate once for _ in chain {} // Iterate again with the copy for _ in chain_copy {} } ``` -------------------------------- ### Handle Validation Errors Source: https://github.com/dtolnay/anyhow/blob/master/_autodocs/errors.md Validate input data like an email address and return errors for constraint violations using anyhow's ensure macro. ```rust use anyhow::{ensure, Result}; fn validate_email(email: &str) -> Result<()> { ensure!(email.contains('@'), "Email must contain @"); ensure!(email.len() >= 5, "Email too short"); Ok(()) } ```