0 Tage Serie
rust / expert
Snippet

Isolierte Panic-Erfassung und Hook-Testen

Das Testen von Panic-Verhalten in Standard-Rust erfordert das Abfangen des Output-Hooks und das sichere Einbetten der Ausführung in std::panic::catch_unwind.

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())
}
}
Erklärung
1
pub fn test_panic_resilience<F>(f: F) -> Result<(), String>
Test-Runner höherer Ordnung, der eine Closure akzeptiert, um Panic-Auslösung zu validieren.
2
let prev_hook = take_hook();
Speichert den bestehenden globalen Panic-Handler vor der Registrierung des eigenen Hooks.
3
let result = catch_unwind(AssertUnwindSafe(f));
Führt Closure aus und fängt Unwinding-Thread-Panics ohne Prozessabbruch ab.
4
set_hook(prev_hook);
Stellt den ursprünglichen globalen Panic-Hook wieder her, um einen sauberen Zustand zu wahren.