pub fn catch_panics<T, E>(
operation: impl FnOnce() -> Result<T, E>,
on_panic: impl FnOnce(String) -> E,
) -> Result<T, E>Expand description
Runs operation, converting any unwinding panic into an error produced by
on_panic instead of letting it escape into the caller. Every embedding
boundary routes through this guard, so an internal invariant violation on
adversarial input becomes a structured, catchable error rather than crashing
or trapping the host.
on_panic receives the panic’s message and maps it to the caller’s own error
type (for example a ValidationError or a binding-specific error type),
keeping the guard reusable across every binding without coupling it to one
error type.
The guard only works under the unwind panic strategy - catch_unwind
intercepts unwinding panics, not aborts. The workspace pins panic = "unwind"
in both the dev and release profiles (src/Cargo.toml), so on native targets
a panic is caught here before it can unwind across an FFI boundary - which
would be undefined behavior.
On wasm32-unknown-unknown the standard library is compiled with
panic = "abort": a panic traps the instance and catch_unwind cannot
intercept it, so the only recovery is to recreate the instance. There this
guard is a no-op that becomes effective only if the wasm build opts into the
unwind strategy. Wrapping the wasm path is therefore harmless and
forward-compatible rather than load-bearing today.