wiwi::prelude_std::panic

Function catch_unwind

1.9.0 · Source
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());