Skip to content
← All Rust tracks

Errors Are Values

Rust

Handle missing values and failures with Option and Result. Propagate errors with ?, define useful error types, and decide when a panic is appropriate.

This track uses Rust. You can make it your practice mode to browse related content across the site.

19 exercises

5 articles

Explore freely. Sign in to keep your progress.

Your learning sequence

  1. 1 Option and Result: absence and failure as values Read
  2. 2 Not solved yet. Matching on Option Practice · Easy
  3. 3 Not solved yet. The Option combinator vocabulary Practice · Easy
  4. 4 Not solved yet. Eager vs lazy defaults Practice · Easy
  5. 5 Not solved yet. Borrowing through Option Practice · Medium
  6. 6 Not solved yet. Mutating an Option in place Practice · Medium
  7. 7 Not solved yet. Result, and why it is #[must_use] Practice · Easy
  8. 8 Not solved yet. Result combinators and map_err Practice · Easy
  9. 9 Not solved yet. Converting between Option and Result Practice · Medium
  10. 10 How the ? operator propagates failure Read
  11. 11 Not solved yet. Propagating with ? Practice · Easy
  12. 12 Not solved yet. ? on Option, and bridging to Result Practice · Medium
  13. 13 When panic! is correct, and when it is a bug Read
  14. 14 Not solved yet. Define a structured validation error Practice · Medium
  15. 15 Not solved yet. From impls: the machinery behind ? Practice · Medium
  16. 16 Not solved yet. Error chains and source() Practice · Medium
  17. 17 Error enums vs Box<dyn Error> Read
  18. 18 Not solved yet. Boxed errors and downcasting Practice · Medium
  19. 19 Not solved yet. Adding context without anyhow Practice · Hard
  20. 20 What thiserror and anyhow actually generate Read
  21. 21 Not solved yet. #[must_use] in depth Practice · Medium
  22. 22 Not solved yet. Collecting an iterator of Results Practice · Medium
  23. 23 Not solved yet. unwrap and expect discipline Practice · Medium
  24. 24 Not solved yet. Documenting failure: # Errors and # Panics Practice · Medium

Check yourself

4 questions · not saved while you're signed out

Use these questions to check your understanding and compare explanations. Your score does not affect track completion.

0 / 4 correct

How can ? propagate ParseIntError from a function returning Result<i32, MyErr>?

Choose one answer to reveal the explanations. Answers are kept only while this page is open.

use std::num::ParseIntError;

#[derive(Debug)]
struct MyErr(ParseIntError);

impl From<ParseIntError> for MyErr {
    fn from(error: ParseIntError) -> Self {
        MyErr(error)
    }
}

fn parse(s: &str) -> Result<i32, MyErr> {
    Ok(s.parse::<i32>()?)
}

fn main() {
    println!("{:?}", parse("21"));
    if let Err(MyErr(error)) = parse("x") {
        println!("parse error: {error}");
    }
}
Question 1 of 4