Skip to content

Chapter 3 of 8

Error Handling with Option and Result

Rust replaces the concept of `null` with the `Option` enum, which has two variants: `Some(T)` when a value is present and `None` when it is absent. Because `Option` is just an enum, the compiler will not let you treat a possibly-absent value as if it were always present; you must explicitly handle the `None` case before you can extract the inner value, which removes null pointer exceptions by construction.

There are several idiomatic ways to work with an `Option`. Calling `unwrap()` returns the inner value or panics if it is `None`, which is appropriate only when you are certain the value exists. `unwrap_or(default)` provides a fallback instead of panicking. `if let Some(v) = opt { ... }` and `match` give you explicit control over both branches. The `?` operator applied to an `Option` returns the inner value when it is `Some` and early-returns `None` to the caller otherwise, which keeps chains of fallible optional operations short and readable.

For operations that can fail in a recoverable way, Rust uses `Result`, an enum with `Ok(T)` for success and `Err(E)` for failure. The `?` operator works on `Result` in the same way: it propagates the error to the caller while letting success flow through. Combined with the `From` trait, this makes error propagation across many layers of code almost as concise as exception handling in other languages, but with statically checked types.

The distinction between `panic!` and `Result` is intentional. A `panic!` is for unrecoverable errors: it unwinds the stack and typically aborts the current thread, which is appropriate for invariant violations and bugs that the program cannot safely continue past. `Result` is for errors the caller should be able to handle, such as a missing file or malformed input. Library code almost always prefers `Result`, while `panic!` is reserved for situations where continuing would corrupt the program's state.

All chapters
  1. 1Foundations of Rust Memory Safety
  2. 2Structures, Enums, and Pattern Matching
  3. 3Error Handling with Option and Result
  4. 4Traits, Generics, and Polymorphism
  5. 5Iterators, Closures, and Functional Patterns
  6. 6Modules, Crates, Cargo, and Testing
  7. 7Concurrency in Rust
  8. 8Smart Pointers and Unsafe Rust

Drill it

Reading is not remembering. These come from the Rust Programming deck:

Q

What is Rust?

Rust is a systems programming language focused on safety, speed, and concurrency. It achieves memory safety without a garbage collector through its ownership sy...

Q

What is ownership in Rust?

Ownership is Rust's core memory management concept. Each value has exactly one owner, and when the owner goes out of scope, the value is dropped (freed). This p...

Q

What are the three ownership rules in Rust?

Each value in Rust has a single ownerThere can only be one owner at a timeWhen the owner goes out of scope, the value is dropped

Q

What is borrowing in Rust?

Borrowing lets you reference a value without taking ownership. You create a reference with &. The original owner retains ownership while the borrower can re...