Skip to main content

ktrs_syntax/
caught_panic.rs

1//! Ported code mimics a Java exception with a panic, caught where the JVM tool catches the exception
2//! (ktlint's rule boundary, ktfmt's per-file `catch`). The default panic hook would still print each
3//! one to stderr, which the jar does not; [`silence_caught_panics`] keeps those quiet.
4
5use std::cell::Cell;
6use std::panic::{self, AssertUnwindSafe};
7use std::sync::Once;
8
9thread_local! {
10    static CATCHING: Cell<bool> = const { Cell::new(false) };
11}
12
13/// `catch_unwind`, marking the panics it catches as expected (silent once the hook is installed).
14pub fn catch_quietly<R>(f: impl FnOnce() -> R) -> std::thread::Result<R> {
15    let outer = CATCHING.replace(true);
16    let result = panic::catch_unwind(AssertUnwindSafe(f));
17    CATCHING.set(outer);
18    result
19}
20
21/// Installs (once per process) a panic hook that stays quiet for panics [`catch_quietly`] catches;
22/// any other panic still prints.
23pub fn silence_caught_panics() {
24    static INSTALL: Once = Once::new();
25    INSTALL.call_once(|| {
26        let previous = panic::take_hook();
27        panic::set_hook(Box::new(move |info| {
28            if !CATCHING.get() {
29                previous(info);
30            }
31        }));
32    });
33}