Course contentsShow
← Rust
Lesson 51 of 1,9101. Rust Fundamentals and ToolingFree lesson

Error Handling via Results

Distinguish between recoverable errors and unrecoverable panics using the Result enum.

In this lesson, you will learn how to distinguish between errors your program can recover from and those that should cause it to stop immediately.

Recoverable vs. Unrecoverable

In Rust, we categorize problems into two types:

  1. Unrecoverable errors: These are catastrophic failures, like trying to access an index outside of an array's bounds. In these cases, we use a panic!, which crashes the program.
  2. Recoverable errors: These are scenarios where the program might fail, but can decide what to do next. For example, failing to open a file because it doesn't exist. We don't want the program to crash; we want to handle the situation.

The Result Enum

To handle recoverable errors, Rust uses the Result enum. You've already learned about enums and pattern matching, so this will look familiar! A Result is defined like this:

enum Result<T, E> {
    Ok(T),
    Err(E),
}
  • Ok(T): This represents success and holds the value T.
  • Err(E): This represents a failure and holds the error information E.

When a function might fail, it returns a Result. You then use a match statement to decide how to proceed.

A Concrete Example

Imagine a function that divides two numbers. If the divisor is zero, we can't perform the math. Instead of crashing, we return a Result:

fn divide(numerator: f64, denominator: f64) -> Result<f64, String> {
    if denominator == 0.0 {
        Err(String::from("Cannot divide by zero"))
    } else {
        Ok(numerator / denominator)
    }
}

fn main() {
    let result = divide(10.0, 0.0);

    match result {
        Ok(value) => println!("The result is {}", value),
        Err(e) => println!("Error encountered: {}", e),
    }
}

By returning a Result, we force the person calling our function to acknowledge the possibility of failure. They must decide whether to print an error message, try again, or take some other corrective action. This makes your programs significantly more robust than those that simply crash when things go wrong.

Key Takeaway: Use panic! for unrecoverable state violations and the Result enum to gracefully handle expected failures during program execution.