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.
Rust functions that are expected to be called from foreign code that does
not support unwinding (such as C compiled with -fno-exceptions
) should be
defined using extern "C"
, which ensures that if the Rust code panics, it
is automatically caught and the process is aborted. If this is the desired
behavior, it is not necessary to use catch_unwind
explicitly. This
function should instead be used when more graceful error-handling is needed.
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
This function might not catch all Rust panics. A Rust panic 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.
If a custom panic hook has been set, it will be invoked before the panic is caught, before unwinding.
Although unwinding into Rust code with a foreign exception (e.g. an
exception thrown from C++ code, or a panic!
in Rust code compiled or
linked with a different runtime) via an appropriate ABI (e.g. "C-unwind"
)
is permitted, catching such an exception using this function will have one
of two behaviors, and it is unspecified which will occur:
- The process aborts, after executing all destructors of
f
and the functions it called. - The function returns a
Result::Err
containing an opaque type.
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());