arcdps/
panic.rs

1//! Panic handling.
2
3use crate::exports::log_to_file;
4use std::{
5    backtrace::Backtrace,
6    ffi::CString,
7    panic::{self, PanicHookInfo},
8};
9use windows::{
10    core::PCSTR,
11    Win32::UI::WindowsAndMessaging::{MessageBoxA, MB_ICONERROR, MB_OK, MB_SETFOREGROUND},
12};
13
14/// Sets up the custom panic hook.
15pub fn init_panic_hook(name: &'static str) {
16    panic::set_hook(Box::new(move |info| {
17        let message = if cfg!(feature = "panic_trace") {
18            let trace = Backtrace::force_capture();
19            format!("error: {name} {info}\n{trace:#}")
20        } else {
21            format!("error: {name} {info}")
22        };
23
24        let _ = log_to_file(message);
25
26        #[cfg(feature = "panic_msgbox")]
27        message_box(name, info);
28    }));
29}
30
31fn message_box(name: &'static str, info: &PanicHookInfo) {
32    let text = CString::new(format!("{name} {info}")).unwrap();
33    let caption = CString::new(format!("{name} error")).unwrap();
34    unsafe {
35        MessageBoxA(
36            None,
37            PCSTR(text.as_ptr().cast()),
38            PCSTR(caption.as_ptr().cast()),
39            MB_OK | MB_ICONERROR | MB_SETFOREGROUND,
40        )
41    };
42}