Rust Tutorial
Estimated reading: 4 minutes 25 views

🦀 Rust – Error Handling: Handle Failures Safely with Result & Option

🧲 Introduction – Why Learn Error Handling in Rust?

Rust’s approach to error handling is explicit, type-safe, and compiler-enforced. Unlike many languages that use exceptions, Rust uses Result and Option enums to model recoverable and non-recoverable errors at compile time, reducing bugs and panics in production code.

🎯 In this guide, you’ll learn:

  • The difference between panic!, Option, and Result
  • How to handle errors with match, unwrap, and ?
  • How to propagate errors in functions
  • Code examples with output and line-by-line explanations

💥 panic! – Non-recoverable Error (Crash on Purpose)

🔹 Code Example:

fn main() {
    panic!("Something went wrong!");
}

📤 Output:

thread 'main' panicked at 'Something went wrong!', src/main.rs:2:5
note: run with `RUST_BACKTRACE=1` for a backtrace

⚠️ Use panic! only when continuing execution is unsafe or meaningless.


❓ Option – Value Might Be Absent

Used when a value might not exist, like indexing or searching.

🔹 Code Example:

fn main() {
    let nums = vec![1, 2, 3];
    match nums.get(5) {
        Some(n) => println!("Found: {}", n),
        None => println!("No value at index"),
    }
}

📤 Output:

No value at index

Option<T> has two variants: Some(value) or None.


📦 Result<T, E> – Recoverable Errors

Used for file operations, network requests, etc.

🔹 Code Example:

use std::fs::File;

fn main() {
    let file = File::open("nonexistent.txt");

    match file {
        Ok(_) => println!("File opened successfully"),
        Err(e) => println!("Failed to open file: {}", e),
    }
}

📤 Output:

Failed to open file: No such file or directory (os error 2)

🔁 Propagating Errors with ? Operator

Use ? to return errors automatically if an operation fails.

🔹 Code Example:

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

fn read_file() -> Result<String, io::Error> {
    let mut file = File::open("data.txt")?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    Ok(contents)
}

fn main() {
    match read_file() {
        Ok(text) => println!("File content:\n{}", text),
        Err(e) => println!("Error reading file: {}", e),
    }
}

? simplifies error handling by bubbling up errors.


💡 unwrap() and expect() – Panic on Error

🔹 Code Example:

fn main() {
    let val: Option<i32> = None;
    // let num = val.unwrap(); // ❌ Panics
    let num = val.expect("Expected a number"); // ❌ Better panic message
}

⚠️ Avoid unwrap() in production unless you’re certain the value is valid.


🔧 Defining Your Own Error Type

For advanced cases, define a custom error type with enum.

use std::fmt;

enum MyError {
    NotFound,
    InvalidInput,
}

impl fmt::Display for MyError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            MyError::NotFound => write!(f, "Item not found"),
            MyError::InvalidInput => write!(f, "Input is invalid"),
        }
    }
}

✅ Custom errors make your APIs expressive and ergonomic.


📊 Option vs Result vs panic!

MechanismUse CaseReturn TypeSafe?
OptionMissing valueSome(T) / None✅ Yes
ResultRecoverable errorsOk(T) / Err(E)✅ Yes
panic!Unrecoverable program failureNever returns❌ No

📌 Summary – Recap & Next Steps

Rust’s error system encourages you to write safe, predictable code. By using Result, Option, and proper error propagation, you build programs that fail gracefully and informatively.

🔍 Key Takeaways:

  • Use Option<T> when absence of value is expected
  • Use Result<T, E> for recoverable I/O and system errors
  • Use ? to simplify error propagation
  • Avoid unwrap() and panic! in production logic

⚙️ Next: Learn about Generics and Traits to write reusable and type-safe Rust functions.


❓FAQs


What does the ? operator do in Rust?
✅ It checks if a result is Err, and if so, returns it early from the function. Otherwise, it unwraps the Ok value.


When should I use Option instead of Result?
✅ Use Option when there’s no meaningful error message—just “value or not.” Use Result when you want to return a specific error type.


Is unwrap() ever safe to use?
✅ It can be used in controlled code (like tests), but in production logic, prefer match, ?, or expect() with custom messages.


Can I define custom error types in Rust?
✅ Yes. Use enum and implement Display, Debug, and optionally std::error::Error.


Share Now :

Leave a Reply

Your email address will not be published. Required fields are marked *

Share

Rust Error Handling

Or Copy Link

CONTENTS
Scroll to Top