Jose Luis
Jose Luis

Reputation: 31

What is the right way to capture panics?

Frequently we don't want our program stopping due to out of bounds, division by 0 or similar panics. However, std::thread::catch_panic is marked us unstable. We could write...

let result = Thread::scoped(move || {
        make_a_division_for_ever()
    }).join();
    if result.is_ok() {
        println!("Finished OK");
    }

Is this the right way to capture panics (like division by 0 or out of bounds)?

A complete example...

use std::thread::Thread;

fn main() {
    println!("Make divisions for ever");

    loop {
        let result = Thread::scoped(move || {
            make_a_division_for_ever()
        }).join();
        if result.is_ok() {
            println!("Finished OK");
        }
        else {
            println!("It CRASHED!!!  restarting...");
        }
    }

}

fn make_a_division_for_ever() {
    loop {
        println!("Enter divisor...");
        let line = std::io::stdin()
                .read_line()
                .ok()
                .expect("error reading line");

        let divisor = line.trim()
                .parse::<u32>()
                .expect("
I coudn't parse your line as an string. I'm going to die
I showed things closer than orion belt...
        ");

        println!("readed {}", divisor);

        let dangerous =  1_000_000 / divisor;

        println!("DIV RESULT... {}", dangerous);
    }
}

Upvotes: 3

Views: 1231

Answers (1)

Manishearth
Manishearth

Reputation: 16188

Rust panics aren't intended to be caught in most cases. Unstable Rust provides this functionality, but you should only be using it if you have a really complex situation (say, you're writing a test harness for other Rust programs and need to hook into the panic handler) where you can't bubble up the error.

In Rust, error handling is done by returning Result<T,E>s (sometimes Option<T>, bubbling them up with try!(), and handling them with match.

Most panicky methods have non-panicky versions; for example a checked version of divide is checked_div(), and you can use try! to return the errors from the string parsing.

Upvotes: 7

Related Questions