liveBook · Manning

Anyhow

As explained in Learn Rust in a Month of Lunches

anyhow is a Rust library for simplifying error handling by representing diverse failure causes through a single dynamically composed error type.

anyhow is a Rust library that gives fallible functions one convenient error type: anyhow::Error, also available through anyhow::Result<T>. It lets the question-mark operator pass along errors from different operations without choosing one concrete error type. section 17.5 section 17.5.1

Use anyhow when a function can fail in several different ways:

  • Return Result<T, anyhow::Error>, or the shorter anyhow::Result<T>, from fallible functions. section 17.5.1
  • Create an error quickly with the anyhow! macro from a message or another error. section 17.5.1
  • Add useful diagnostic details with .with_context(), such as the input that could not be parsed. section 17.5.1
  • Choose thiserror instead when you need to define a named error type for other code to inspect. section 17.5 section 17.5.1

Parsing and sending a number

A function can convert bytes to text, parse an i32, and send the number while propagating each possible failure with ?. If the number is too large, anyhow!("Number is too large") creates the same general error type. Calling parse_then_send(b"nine") reports the parsing failure; adding with_context supplies a clearer message such as “Got a weird str to parse: nine.” section 17.5.1

use anyhow::{anyhow, Context, Error};
 
fn parse_then_send(input: &[u8]) -> Result<(), Error> {
    let some_str = std::str::from_utf8(input)
    .with_context(|| "Couldn't parse into a str")?;
    let number = some_str
        .parse::<i32>()
        .with_context(|| format!("Got a weird str to parse: {some_str}"))?;
    send_number(number)?;
    Ok(())
}
 
fn send_number(number: i32) -> Result<(), Error> {
    if number < 1_000_000 {
        println!("Number sent!");
        Ok(())
    } else {
        println!("Too large!");
        Err(anyhow!("Number is too large"))
    }
}
 
fn main() {
    println!("{:?}", parse_then_send(b"nine"));
    println!("{:?}", parse_then_send(b"10"));
}

The complete example shows anyhow error construction, question-mark propagation, and contextual messages in one small Rust program. section 17.5.1

How Learn Rust in a Month of Lunches covers it

How deep it goes
Explains return types, propagation, construction, and context with code, but stops short of implementing custom error types.
Examples
Demonstrates byte-to-string conversion, integer parsing, numeric validation, anyhow!, and with_context.
What you can do after
Apply it via the anyhow crate to propagate mixed errors and add readable diagnostic context.
How it connects
Connects anyhow with Result, the question-mark operator, std::error::Error, and thiserror.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Rust in a Month of Lunches. The section links point to the parts of the book it draws on.