diff options
Diffstat (limited to 'libs/all_in_one/src/errors.rs')
| -rw-r--r-- | libs/all_in_one/src/errors.rs | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/libs/all_in_one/src/errors.rs b/libs/all_in_one/src/errors.rs new file mode 100644 index 0000000..d2c7444 --- /dev/null +++ b/libs/all_in_one/src/errors.rs @@ -0,0 +1,53 @@ +use std::cell::RefCell; + +use anyhow::Result; +use tracing::error; + +thread_local! { + pub static ERROR_HANDLER: std::cell::RefCell<Option<unsafe extern "C" fn(libc::c_int, *mut libc::c_char)>> = RefCell::new(None); +} + +/// Update the most recent error, clearing whatever may have been there before. +#[must_use] pub fn stacktrace(err: &anyhow::Error) -> String { + format!("{err}") +} + +pub fn wrap_result<T, F>(func: F) -> Option<T> +where + F: Fn() -> Result<T>, +{ + let result = func(); + + match result { + Ok(ok) => Some(ok), + Err(error) => { + // Call the handler + handle_error(&error); + None + } + } +} + +/// # Panics +/// Panics if the stacktrace size is > than an i32 +pub fn handle_error(error: &anyhow::Error) { + ERROR_HANDLER.with(|val| { + let mut stacktrace = stacktrace(error); + + error!("Error emitted: {}", stacktrace); + if let Some(func) = *val.borrow() { + // Call the error handler + unsafe { + func( + (stacktrace.len() + 1).try_into().unwrap(), + stacktrace.as_mut_ptr().cast::<libc::c_char>(), + ); + } + } + }); +} + +#[cfg(test)] +mod tests { + // todo +} |
