I'm working on a Rust wrapper for the Duktape JavaScript interpreter. In a normal use case, the call stack will look like this:
What happens if (5) calls panic!
? According to various Rust developers on IRC, attempting to panic!
from inside non-Rust callframes like (3) may result in undefined behavior.
But according the Rust documentation, the only way to catch a panic!
is using std::task::try
, which spawns an extra thread. There's also rustrt::unwind::try
, which cannot be nested twice within a single thread, among other restrictions.
One solution, proposed by Benjamin Herr, is to abort the process if the code in (5) panics. I've packaged his solution as abort_on_panic
, and it appears to work, for values of "work" that include "crashing the entire program, but at least not corrupting things subtly":
abort_on_panic!("cannot panic inside this block", {
panic!("something went wrong!");
});
But is a way to emulate std::task::try
without the overhead of thread/task creation?
As of Rust 1.9.0, you can use panic::catch_unwind
to recover the error:
use std::panic;
fn main() {
let result = panic::catch_unwind(|| {
panic!("oh no!");
});
assert!(result.is_err());
}
Passing it to the next layer is just as easy with panic::resume_unwind
:
use std::panic;
fn main() {
let result = panic::catch_unwind(|| {
panic!("oh no!");
});
if let Err(e) = result {
panic::resume_unwind(e);
}
}
Editor's note: This answer predates Rust 1.0 and is no longer necessarily accurate. Other answers still contain valuable information.
You cannot 'catch' a panic!
. It terminates execution of the current thread. Therefore, without spinning up a new one to isolate, it's going to terminate the thread you're in.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With