0 day streak
rust / expert
Snippet

Isolated Panic Catching and Hook Testing

Unit testing panic behavior in standard Rust requires intercepting output hooks and wrapping execution inside std::panic::catch_unwind safely.

snippet.rs
rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
use std::panic::{catch_unwind, set_hook, take_hook, AssertUnwindSafe};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
pub fn test_panic_resilience<F>(f: F) -> Result<(), String>
where
F: FnOnce() + Send + 'static,
{
let hook_called = Arc::new(AtomicBool::new(false));
let hook_flag = Arc::clone(&hook_called);
let prev_hook = take_hook();
set_hook(Box::new(move |_info| {
hook_flag.store(true, Ordering::SeqCst);
}));
let result = catch_unwind(AssertUnwindSafe(f));
set_hook(prev_hook);
if result.is_err() && hook_called.load(Ordering::SeqCst) {
Ok(())
} else {
Err("Expected thread panic was not triggered or caught".to_string())
}
}
Breakdown
1
pub fn test_panic_resilience<F>(f: F) -> Result<(), String>
Higher-order test runner accepting a closure to validate panic invocation.
2
let prev_hook = take_hook();
Saves existing global panic handler prior to registering custom hook.
3
let result = catch_unwind(AssertUnwindSafe(f));
Executes closure while catching unwinding thread panics without process termination.
4
set_hook(prev_hook);
Restores original global panic hook to maintain environment clean state.