Module 6 • Lesson 30

Panics and Unrecoverable Errors

📚 7 min💻 Free🦀 nixus.pro

Panics: When Things Go Catastrophically Wrong

Rust has two categories of errors: recoverable (Result/Option) and unrecoverable (panic). Panics are for bugs - things that should never happen.

fn main() {
    // Direct panic
    // panic!("Something went terribly wrong");

    // Panics from invalid operations
    let v = vec![1, 2, 3];
    // v[10]; // index out of bounds - panics!
    // 5 / 0; // integer division by zero - panics!

    // unwrap and expect panic on None/Err
    let x: Option = None;
    // x.unwrap(); // called `Option::unwrap()` on a `None` value
    // x.expect("x should always be Some"); // Better panic message

    // Use panic for programming errors, not user errors:
    fn divide(a: i32, b: i32) -> i32 {
        assert!(b != 0, "Division by zero is a programming error");
        a / b
    }

    // Catching panics (rarely needed - prefer Result)
    use std::panic;
    let result = panic::catch_unwind(|| {
        42 // or: panic!("oops")
    });
    println!("{:?}", result); // Ok(42)

    // In tests, you can assert panics:
    // #[should_panic(expected = "divide by zero")]
    // fn test_divide_by_zero() { divide(1, 0); }
}

When to Panic

// PANIC when: it is a programming error (impossible state)
fn get_first(v: &[i32]) -> i32 {
    assert!(!v.is_empty(), "Cannot get first of empty slice");
    v[0]
}

// RETURN Result when: it is a user/runtime error (expected to happen)
fn parse_config(s: &str) -> Result {
    s.trim().parse::().map_err(|e| format!("Invalid port: {}", e))
}

// Useful assertion macros:
fn assertions_demo() {
    assert!(1 + 1 == 2);
    assert_eq!(4, 2 + 2);
    assert_ne!(5, 2 + 2);
    assert!(true, "Optional message: {}", "with formatting");
    debug_assert!(1 == 1); // Only in debug builds, optimized away in release
}

🎯 Practice

  1. Write a function that panics with a clear message when given negative input
  2. Use assert_eq! and assert_ne! in a test function (with #[test])
  3. Use panic::catch_unwind to test that a function panics in specific conditions

🎉 Key Takeaways