Rust's Error Handling Without Exceptions | Generated by AI

Home PDF

Rust does not have exceptions in the traditional sense, like Java or C#. Instead, it handles errors primarily through return values, similar to Go’s if err != nil pattern, but with a more robust and type-safe approach.

Here’s a breakdown of how Rust handles errors:

1. Result<T, E> Enum for Recoverable Errors:

This is the most common and idiomatic way to handle errors in Rust.

Example:

use std::fs::File;
use std::io::ErrorKind;

fn main() {
    let greeting_file_result = File::open("hello.txt");

    let greeting_file = match greeting_file_result {
        Ok(file) => file,
        Err(error) => match error.kind() {
            ErrorKind::NotFound => match File::create("hello.txt") {
                Ok(fc) => fc,
                Err(e) => panic!("Problem creating the file: {:?}", e),
            },
            other_error => panic!("Problem opening the file: {:?}", other_error),
        },
    };

    println!("Successfully opened or created file: {:?}", greeting_file);
}

2. Option<T> Enum for Optional Values:

While not strictly for “errors,” Option<T> is similar to Result in that it represents the possibility of absence.

3. The ? Operator (Question Mark Operator):

This is a powerful syntactic sugar that makes propagating errors much more concise, similar to how if err != nil { return err } is common in Go.

Example with ?:

use std::fs::File;
use std::io::{self, Read}; // Import io::Read trait

fn read_username_from_file() -> Result<String, io::Error> {
    let mut username_file = File::open("hello.txt")?; // Propagates error if file doesn't exist
    let mut username = String::new();
    username_file.read_to_string(&mut username)?; // Propagates error if reading fails
    Ok(username)
}

fn main() {
    match read_username_from_file() {
        Ok(username) => println!("Username: {}", username),
        Err(e) => println!("Error reading username: {}", e),
    }
}

4. panic! Macro for Unrecoverable Errors:

panic! is used for unrecoverable errors, which typically indicate a bug in the program (e.g., accessing an array out of bounds).

Key Differences from Traditional Exceptions:

In summary, Rust’s error handling model is much closer to Go’s “check in every level” philosophy than to Java’s or C#’s exceptions. However, with the Result enum and the ? operator, Rust provides powerful and ergonomic tools to make this explicit error handling manageable and even enjoyable.


Back 2025.06.30 Donate