Skip to main content

wp_error/error_handling/
strategy.rs

1use serde::{Deserialize, Serialize};
2use std::{
3    fmt::Formatter,
4    sync::atomic::{AtomicU8, Ordering},
5};
6use wp_log::{error_ctrl, warn_ctrl};
7
8pub enum ErrorHandlingStrategy {
9    FixRetry,
10    Tolerant,
11    Throw,
12    Ignore,
13    Terminate,
14}
15
16static ROBUST_MODE: AtomicU8 = AtomicU8::new(0);
17//static mut ROBUST_MODE: RobustnessMode = RobustnessMode::Debug;
18
19pub fn sys_robust_mode() -> RobustnessMode {
20    match ROBUST_MODE.load(Ordering::SeqCst) {
21        0 => RobustnessMode::Debug,
22        1 => RobustnessMode::Normal,
23        2 => RobustnessMode::Strict,
24        _ => unreachable!("Invalid robustness mode"),
25    }
26}
27
28pub fn switch_sys_robust_mode(mode: RobustnessMode) -> RobustnessMode {
29    let old = sys_robust_mode();
30    let new_mode = match mode {
31        RobustnessMode::Debug => 0,
32        RobustnessMode::Normal => 1,
33        RobustnessMode::Strict => 2,
34    };
35    // runtime-level change is part of engine control plane
36    warn_ctrl!("switch robust mode from {} to {}", old, mode);
37    ROBUST_MODE.store(new_mode, Ordering::SeqCst);
38    old
39}
40
41#[derive(Debug, Default, PartialEq, Deserialize, Serialize, Clone)]
42pub enum RobustnessMode {
43    #[default]
44    #[serde(rename = "debug")]
45    Debug,
46    #[serde(rename = "normal")]
47    Normal,
48    #[serde(rename = "strict")]
49    Strict,
50}
51
52impl From<&str> for RobustnessMode {
53    fn from(s: &str) -> Self {
54        match s {
55            "debug" => RobustnessMode::Debug,
56            "normal" => RobustnessMode::Normal,
57            "strict" => RobustnessMode::Strict,
58            other => {
59                // Fallback to debug to avoid panic in production; log a warning.
60                error_ctrl!("unknown robust mode '{}', fallback to 'debug'", other);
61                RobustnessMode::Debug
62            }
63        }
64    }
65}
66
67impl std::fmt::Display for RobustnessMode {
68    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
69        match self {
70            RobustnessMode::Debug => write!(f, "debug"),
71            RobustnessMode::Normal => write!(f, "normal"),
72            RobustnessMode::Strict => write!(f, "strict"),
73        }
74    }
75}
76
77#[cfg(test)]
78mod tests {
79    use super::*;
80
81    #[test]
82    fn test_robustness_mode_default() {
83        let mode = RobustnessMode::default();
84        assert_eq!(mode, RobustnessMode::Debug);
85    }
86
87    #[test]
88    fn test_robustness_mode_from_str_debug() {
89        let mode = RobustnessMode::from("debug");
90        assert_eq!(mode, RobustnessMode::Debug);
91    }
92
93    #[test]
94    fn test_robustness_mode_from_str_normal() {
95        let mode = RobustnessMode::from("normal");
96        assert_eq!(mode, RobustnessMode::Normal);
97    }
98
99    #[test]
100    fn test_robustness_mode_from_str_strict() {
101        let mode = RobustnessMode::from("strict");
102        assert_eq!(mode, RobustnessMode::Strict);
103    }
104
105    #[test]
106    fn test_robustness_mode_from_str_unknown() {
107        let mode = RobustnessMode::from("unknown");
108        assert_eq!(mode, RobustnessMode::Debug); // fallback
109    }
110
111    #[test]
112    fn test_robustness_mode_display() {
113        assert_eq!(RobustnessMode::Debug.to_string(), "debug");
114        assert_eq!(RobustnessMode::Normal.to_string(), "normal");
115        assert_eq!(RobustnessMode::Strict.to_string(), "strict");
116    }
117
118    #[test]
119    fn test_robustness_mode_serde() {
120        let json = "\"debug\"";
121        let mode: RobustnessMode = serde_json::from_str(json).unwrap();
122        assert_eq!(mode, RobustnessMode::Debug);
123
124        let json = "\"normal\"";
125        let mode: RobustnessMode = serde_json::from_str(json).unwrap();
126        assert_eq!(mode, RobustnessMode::Normal);
127
128        let json = "\"strict\"";
129        let mode: RobustnessMode = serde_json::from_str(json).unwrap();
130        assert_eq!(mode, RobustnessMode::Strict);
131    }
132
133    #[test]
134    fn test_robustness_mode_serialize() {
135        assert_eq!(
136            serde_json::to_string(&RobustnessMode::Debug).unwrap(),
137            "\"debug\""
138        );
139        assert_eq!(
140            serde_json::to_string(&RobustnessMode::Normal).unwrap(),
141            "\"normal\""
142        );
143        assert_eq!(
144            serde_json::to_string(&RobustnessMode::Strict).unwrap(),
145            "\"strict\""
146        );
147    }
148
149    #[test]
150    fn test_robustness_mode_clone() {
151        let mode = RobustnessMode::Normal;
152        let cloned = mode.clone();
153        assert_eq!(mode, cloned);
154    }
155}