pub fn catch_unwind<F, R>(f: F) -> Result<R, Box<dyn Any + Send>>where
F: FnOnce() -> R + UnwindSafe,
Expand description
Invokes a closure, capturing the cause of an unwinding panic if one occurs.
This function will return Ok
with the closure’s result if the closure
does not panic, and will return Err(cause)
if the closure panics. The
cause
returned is the object with which panic was originally invoked.
It is currently undefined behavior to unwind from Rust code into foreign code, so this function is particularly useful when Rust is called from another language (normally C). This can run arbitrary Rust code, capturing a panic and allowing a graceful handling of the error.
It is not recommended to use this function for a general try/catch
mechanism. The Result
type is more appropriate to use for functions that
can fail on a regular basis. Additionally, this function is not guaranteed
to catch all panics, see the “Notes” section below.
The closure provided is required to adhere to the UnwindSafe
trait to ensure
that all captured variables are safe to cross this boundary. The purpose of
this bound is to encode the concept of exception safety in the type
system. Most usage of this function should not need to worry about this
bound as programs are naturally unwind safe without unsafe
code. If it
becomes a problem the AssertUnwindSafe
wrapper struct can be used to quickly
assert that the usage here is indeed unwind safe.
§Notes
Note that this function might not catch all panics in Rust. A panic in Rust is not always implemented via unwinding, but can be implemented by aborting the process as well. This function only catches unwinding panics, not those that abort the process.
Note that if a custom panic hook has been set, it will be invoked before the panic is caught, before unwinding.
Also note that unwinding into Rust code with a foreign exception (e.g. an exception thrown from C++ code) is undefined behavior.
Finally, be careful in how you drop the result of this function.
If it is Err
, it contains the panic payload, and dropping that may in turn panic!
§Examples
use std::panic;
let result = panic::catch_unwind(|| {
println!("hello!");
});
assert!(result.is_ok());
let result = panic::catch_unwind(|| {
panic!("oh no!");
});
assert!(result.is_err());