leetcode_tui_config/
error_handling.rs

1use crate::constants::*;
2use color_eyre::eyre::Result;
3use tracing::error;
4use tracing_error::ErrorLayer;
5use tracing_subscriber::{
6    self, prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt, Layer,
7};
8
9use crate::utils::get_data_dir;
10
11pub fn initialize_panic_handler() -> Result<()> {
12    let (panic_hook, eyre_hook) = color_eyre::config::HookBuilder::default()
13        .panic_section(format!(
14            "This is a bug. Consider reporting it at {}",
15            env!("CARGO_PKG_REPOSITORY")
16        ))
17        .capture_span_trace_by_default(false)
18        .display_location_section(false)
19        .display_env_section(false)
20        .into_hooks();
21    eyre_hook.install()?;
22    std::panic::set_hook(Box::new(move |panic_info| {
23        if let Ok(mut t) = leetcode_tui_shared::tui::Term::start() {
24            if let Err(r) = t.exit() {
25                error!("Unable to exit Terminal: {:?}", r);
26            }
27        }
28
29        #[cfg(not(debug_assertions))]
30        {
31            use human_panic::{handle_dump, print_msg, Metadata};
32            let meta = Metadata {
33                version: env!("CARGO_PKG_VERSION").into(),
34                name: env!("CARGO_PKG_NAME").into(),
35                authors: env!("CARGO_PKG_AUTHORS").replace(':', ", ").into(),
36                homepage: env!("CARGO_PKG_HOMEPAGE").into(),
37            };
38
39            let file_path = handle_dump(&meta, panic_info);
40            // prints human-panic message
41            print_msg(file_path, &meta)
42                .expect("human-panic: printing error message to console failed");
43            eprintln!("{}", panic_hook.panic_report(panic_info)); // prints color-eyre stack trace to stderr
44        }
45        let msg = format!("{}", panic_hook.panic_report(panic_info));
46        log::error!("Error: {}", strip_ansi_escapes::strip_str(msg));
47
48        #[cfg(debug_assertions)]
49        {
50            // Better Panic stacktrace that is only enabled when debugging.
51            better_panic::Settings::auto()
52                .most_recent_first(false)
53                .lineno_suffix(true)
54                .verbosity(better_panic::Verbosity::Full)
55                .create_panic_handler()(panic_info);
56        }
57
58        std::process::exit(libc::EXIT_FAILURE);
59    }));
60    Ok(())
61}
62
63pub fn initialize_logging() -> Result<()> {
64    let directory = get_data_dir();
65    std::fs::create_dir_all(directory.clone())?;
66    let log_path = directory.join(LOG_FILE.get().unwrap().clone());
67    let log_file = std::fs::File::create(log_path)?;
68    std::env::set_var(
69        "RUST_LOG",
70        std::env::var("RUST_LOG")
71            .or_else(|_| std::env::var(LOG_ENV.get().unwrap().clone()))
72            .unwrap_or_else(|_| format!("{}=info", env!("CARGO_CRATE_NAME"))),
73    );
74    let file_subscriber = tracing_subscriber::fmt::layer()
75        .with_file(true)
76        .with_line_number(true)
77        .with_writer(log_file)
78        .with_target(false)
79        .with_ansi(false)
80        .with_filter(tracing_subscriber::filter::EnvFilter::from_default_env());
81    tracing_subscriber::registry()
82        .with(file_subscriber)
83        .with(ErrorLayer::default())
84        .init();
85    Ok(())
86}
87
88/// Similar to the `std::dbg!` macro, but generates `tracing` events rather
89/// than printing to stdout.
90///
91/// By default, the verbosity level for the generated events is `DEBUG`, but
92/// this can be customized.
93#[macro_export]
94macro_rules! trace_dbg {
95    (target: $target:expr, level: $level:expr, $ex:expr) => {{
96        match $ex {
97            value => {
98                tracing::event!(target: $target, $level, ?value, stringify!($ex));
99                value
100            }
101        }
102    }};
103    (level: $level:expr, $ex:expr) => {
104        trace_dbg!(target: module_path!(), level: $level, $ex)
105    };
106    (target: $target:expr, $ex:expr) => {
107        trace_dbg!(target: $target, level: tracing::Level::DEBUG, $ex)
108    };
109    ($ex:expr) => {
110        trace_dbg!(level: tracing::Level::DEBUG, $ex)
111    };
112}