Why Result exists
In languages with exceptions, every function call is implicitly fallible — you can't tell from a signature whether a function might unwind your stack. Rust takes the opposite path: failure is encoded in the return type as an enum, `Result<T, E>`. The signature alone tells you whether a call can fail. The compiler ensures you handle the Err case (or explicitly delegate it). There is no hidden control flow; every error path is visible in the source.
The ? operator
Inside a function returning `Result<T, E>`, the `?` operator on an inner Result either unwraps Ok or returns the Err. With the `From` trait, the error type can auto-convert: a function returning `Result<_, MyError>` can call inner functions returning `Result<_, io::Error>` if `MyError: From<io::Error>` is implemented. This is how libraries compose error types without manual conversion noise.
For deeper background, see a complete cheat-sheet of std collection complexities for the broader context behind this section.
anyhow vs thiserror
For application code, the `anyhow` crate adds `Result<T>` (where E is `anyhow::Error`) with `.context("description")` chaining and a unified error type. For library code, the `thiserror` crate generates structured error enums with `From` impls. Use anyhow when you don't care about the error type at the boundary, thiserror when you do.
Pattern matching and combinators
Every Option combinator has a Result equivalent: `map`, `map_err`, `and_then`, `or_else`, `unwrap_or`. Use `map_err` to wrap or transform the error variant without touching Ok. Use `and_then` to chain another fallible operation. The `?` operator handles 95% of cases; combinators cover the rest.
For deeper background, see the official Rust API guidelines for module-level design for the broader context behind this section.
Common pitfalls
Don't pepper code with `unwrap()` — every call is a hidden panic site. The `?` operator is almost always what you want. Don't make every function return `Result<_, Box<dyn Error>>` — use a concrete enum or anyhow::Error so callers can match on the variant if they need to recover.