`anyhow::Result<T>` is `Result<T, anyhow::Error>` — a type-erased error that captures any other error AND adds context via `.context()`. The app-author's pick (use thiserror for libraries).
Encode "this might fail" in the type signature instead of throwing. Force the caller to handle both branches at compile time. Better than try/catch for foreseeable failures.
If you don't want the thiserror/anyhow dependency, `Box<dyn std::error::Error>` works as a catch-all. The `?` operator promotes any concrete error via `From`.
`Result<T, E>` chains like `Option`. The `?` operator unwraps `Ok` or early-returns the `Err`, converting via `From` so callers can use one error type for many sources.
The `thiserror` crate generates a clean `Error + Display + Debug` impl from an enum, with automatic `From` conversions. The library-author's error-type tool of choice.