aboutsummaryrefslogtreecommitdiff
path: root/examples/example-panic-unwind/src/main.rs
blob: 18cf4d66d3010405bbe19348b8e03cd50a872539 (plain) (blame)
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//! Example Panic Unwind
//!
//! > This example introduces how to catch Panic in the Mingling program loop
//!
//! Run:
//! ```bash
//! cargo run --manifest-path examples/example-panic-unwind/Cargo.toml --quiet -- panic
//! cargo run --manifest-path examples/example-panic-unwind/Cargo.toml --quiet -- panic OhMyGod
//! ```
//!
//! Output:
//! ```plaintext
//! Program not panic
//! Program panic: OhMyGod
//! OhMyGod
//! ```

use mingling::{hook::ProgramHook, prelude::*};

dispatcher!("panic", CMDPanic => EntryPanic);
pack!(NotPanic = ());

fn main() {
    let mut program = ThisProgram::new();
    program.with_dispatcher(CMDPanic);

    // --------- IMPORTANT ---------
    // Enable silence_panic to suppress automatic Panic output
    program.stdout_setting.silence_panic = true;

    // Define a hook to output &ProgramPanic when a Panic occurs
    program
        .with_hook(ProgramHook::empty().on_exec_panic(|info| println!("Program panic: {}", info)));
    // --------- IMPORTANT ---------

    program.exec();
}

#[chain]
fn handle_panic(prev: EntryPanic) -> Next {
    let panic_info = prev.pick::<Option<String>>(()).unpack();
    match panic_info {
        Some(s) => {
            // Panic happens here, will be caught
            panic!("{}", s)
        }
        None => NotPanic::default(),
    }
}

#[renderer]
fn render(_: NotPanic) {
    r_println!("Program not panic");
}

gen_program!();