fn r#catch()

in key/aziot-key-openssl-engine-shared/src/lib.rs [82:115]


fn r#catch<T>(
    function: Option<fn() -> openssl_errors::Function<Error>>,
    f: impl FnOnce() -> Result<T, Box<dyn std::error::Error>>,
) -> Result<T, ()> {
    match f() {
        Ok(value) => Ok(value),
        Err(err) => {
            // Technically, the order the errors should be put onto the openssl error stack is from root cause to top error.
            // Unfortunately this is backwards from how Rust errors work, since they are top error to root cause.
            //
            // We could do it the right way by collect()ing into a Vec<&dyn Error> and iterating it backwards,
            // but it seems too wasteful to be worth it. So just put them in the wrong order.

            if let Some(function) = function {
                openssl_errors::put_error!(function(), Error::MESSAGE, "{}", err);
            } else {
                eprintln!("[aziot-key-openssl-engine-shared] error: {err}");
            }

            let mut source = err.source();
            while let Some(err) = source {
                if let Some(function) = function {
                    openssl_errors::put_error!(function(), Error::MESSAGE, "{}", err);
                } else {
                    eprintln!("[aziot-key-openssl-engine-shared] caused by: {err}");
                }

                source = err.source();
            }

            Err(())
        }
    }
}