Putting aside "you should be using Result
where possible," yes, this is basically how you catch a panic in Rust. Keep in mind that "recover" is perhaps not the best way of phrasing this in Rust. You don't really recover from panics in Rust, you isolate them, then detect them. There is no On Error Resume Next
:P.
That said, there are two things to add to your example. First is how to get at the panic message. The key observation is that Any
, in order to be used, must be explicitly downcast to the exact, concrete type it contains. In this case, since the panic message is a &'static str
, you need to downcast to that.
The second thing is that there is a new API in nightly called catch_panic
that lets you isolate a panic without having to start a thread. That said, it comes with the same restrictions as spawning a new thread: you cannot pass a non-'static
reference across the isolation boundary. Note that this is an unstable addition; there are no guarantees about stability yet, and you'll need a nightly compiler to access it.
Here is an example which shows both of those. You can also run this on the Rust Playpen.
#![feature(catch_panic)]
use std::thread;
fn main() {
println!("Hello, world!");
let h = thread::spawn(|| {
thread::sleep_ms(500);
panic!("boom");
});
let r = h.join();
handle(r);
let r = thread::catch_panic(|| {
thread::sleep_ms(500);
panic!(String::from("boom again!"));
});
handle(r);
println!("Exiting main!");
}
fn handle(r: thread::Result<()>) {
match r {
Ok(r) => println!("All is well! {:?}", r),
Err(e) => {
if let Some(e) = e.downcast_ref::<&'static str>() {
println!("Got an error: {}", e);
} else {
println!("Got an unknown error: {:?}", e);
}
}
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…