use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{Arc, Mutex};
use noesis_runtime::diagnostics as diag;
#[test]
fn panicking_handler_is_contained_not_aborting() {
if let (Ok(name), Ok(key)) = (
std::env::var("NOESIS_LICENSE_NAME"),
std::env::var("NOESIS_LICENSE_KEY"),
) {
noesis_runtime::set_license(&name, &key);
}
noesis_runtime::init();
let prev_hook = std::panic::take_hook();
std::panic::set_hook(Box::new(|_| {}));
let entered = Arc::new(AtomicUsize::new(0));
{
let entered2 = Arc::clone(&entered);
let _guard = diag::set_error_handler(move |_file, _line, _msg, _fatal| {
entered2.fetch_add(1, Ordering::SeqCst);
panic!("user error handler deliberately panics");
});
diag::invoke_error("panic.cpp", 1, false, "boom one");
diag::invoke_error("panic.cpp", 2, false, "boom two");
}
assert_eq!(
entered.load(Ordering::SeqCst),
2,
"the panicking handler must have been entered for each invoke"
);
let seen: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(Vec::new()));
{
let seen2 = Arc::clone(&seen);
let _guard = diag::set_error_handler(move |_file, _line, msg, _fatal| {
seen2.lock().unwrap().push(msg.to_string());
});
diag::invoke_error("ok.cpp", 3, false, "still alive");
}
assert_eq!(
seen.lock().unwrap().as_slice(),
["still alive".to_string()],
"engine must keep dispatching errors normally after a contained panic"
);
std::panic::set_hook(prev_hook);
noesis_runtime::shutdown();
}