Skip to main content

catch_panic

Function catch_panic 

Source
pub fn catch_panic(f: impl FnOnce() -> igraph_error_t) -> igraph_error_t
Expand description

Runs a Rust closure invoked from C (a callback), catching panics so that they never unwind across the FFI boundary.

If f panics, the payload is stored and IGRAPH_INTERRUPTED is returned to igraph, which stops the computation; the next check on the same thread then resumes the panic in Rust code. Use it in every extern "C" fn trampoline that calls user code:

ⓘ
unsafe extern "C" fn trampoline(/* ... */, extra: *mut c_void) -> igraph_error_t {
    catch_panic(|| { /* call the user closure */ igraph_error_type_t_IGRAPH_SUCCESS })
}

f runs in a new level of igraph’s finally stack (IGRAPH_FINALLY_ENTER / IGRAPH_FINALLY_EXIT): when an igraph call made by f fails, the error handler frees the temporaries of that call only, not those of the igraph function that invoked the callback and is still running (see the module docs).

use igraph::{error::{catch_panic, check}, ffi};
// Outside of a callback the finally stack is empty, and stays so.
let code = catch_panic(|| {
    // A failing igraph call inside the "callback" is an ordinary `Err`.
    assert!(igraph::prelude::Graph::new(2, false).add_edge(0, 5).is_err());
    ffi::igraph_error_type_t_IGRAPH_SUCCESS
});
assert!(check(code).is_ok());
assert_eq!(igraph::error::finally_stack_size(), 0);