yfunc_rust/
error.rs

1use crate::prelude::*;
2
3pub type YRes<T> = Result<T, YError>;
4
5pub const INTERNAL_ERROR: &str = "INTERNAL_ERROR";
6
7#[derive(Debug, Clone)]
8pub struct YError {
9    pub code: String,
10    pub msg: String,
11    pub module: String,
12    pub file: String,
13    pub line: u32,
14    pub trace: Vec<String>,
15}
16
17impl YError {
18
19    pub fn upgrade(mut self, err: YError) -> Self {
20        self.code = err.code;
21        self.msg = err.msg;
22        self
23    }
24
25    pub fn code(mut self, code: &str) -> Self {
26        self.code = code.to_string();
27        self
28    }
29
30    pub fn msg(mut self, msg: &str) -> Self {
31        self.msg = msg.to_string();
32        self
33    }
34
35    pub fn trace(mut self, ctx: String) -> Self {
36        self.trace.push(ctx);
37        self
38    }
39
40    pub fn is_internal(&self) -> bool {
41        self.code == INTERNAL_ERROR
42    }
43
44}
45
46impl From<diesel::result::Error> for YError {
47    fn from(err: diesel::result::Error) -> YError {
48        err!("got diesel::result::Error").trace(ctx!("YError::From<diesel::result::Error>", err))
49    }
50}
51
52pub trait Trace {
53    fn upgrade(self, err: YError) -> Self;
54    fn upgrade_if(self, code: &str, err: YError) -> Self;
55    fn code(self, code: &str) -> Self;
56    fn msg(self, msg: &str) -> Self;
57    fn trace(self, ctx: String) -> Self;
58}
59
60impl<T> Trace for YRes<T> {
61
62    fn upgrade(mut self, new_err: YError) -> Self {
63        if let Err(err) = &mut self {
64            err.code = new_err.code;
65            err.msg = new_err.msg;
66        }
67        self
68    }
69
70    fn upgrade_if(mut self, code: &str, new_err: YError) -> Self {
71        if let Err(err) = &mut self {
72            if err.code == code {
73                err.code = new_err.code;
74                err.msg = new_err.msg;
75            }
76        }
77        self
78    }
79
80    fn code(mut self, code: &str) -> Self {
81        if let Err(err) = &mut self {
82            err.code = code.to_string();
83        }
84        self
85    }
86
87    fn msg(mut self, msg: &str) -> Self {
88        if let Err(err) = &mut self {
89            err.msg = msg.to_string();
90        }
91        self
92    }
93
94    fn trace(mut self, ctx: String) -> Self {
95        if let Err(err) = &mut self {
96            err.trace.push(ctx)
97        }
98        self
99    }
100
101}
102
103#[macro_export]
104macro_rules! ctx {
105    () => {
106        format!("MODULE={}, FILE={}, LINE={}", module_path!(), file!(), line!())
107    };
108    ($process:literal) => {
109        format!("{}, MODULE={}, FILE={}, LINE={}", $process, module_path!(), file!(), line!())
110    };
111    ($process:literal, $($value:expr),*) => {{
112        let mut ctx = format!("{}, ", $process);
113        $(
114            let var_trace = format!("{}={:?}, ", stringify!($value), $value);
115            ctx.push_str(&var_trace);
116        )*
117        ctx.push_str(&format!("MODULE={}, FILE={}, LINE={}", module_path!(), file!(), line!()));
118        ctx
119    }};
120    ($($value:expr),*) => {{
121        let mut ctx = String::new();
122        $(
123            let var_trace = format!("{}={:?}, ", stringify!($value), $value);
124            ctx.push_str(&var_trace);
125        )*
126        ctx.push_str(&format!("MODULE={}, FILE={}, LINE={}", module_path!(), file!(), line!()));
127        ctx
128    }};
129}
130
131#[macro_export]
132macro_rules! err {
133    () => {
134        YError { 
135            code: INTERNAL_ERROR.to_string(), 
136            msg: "".to_string(),
137            module: module_path!().to_string(),
138            file: file!().to_string(), 
139            line: line!(),
140            trace: vec![],
141        }
142    };
143    ($msg:literal) => {
144        YError { 
145            code: INTERNAL_ERROR.to_string(), 
146            msg: $msg.to_string(),
147            module: module_path!().to_string(),
148            file: file!().to_string(), 
149            line: line!(),
150            trace: vec![],
151        }
152    };
153    ($msg:literal, $($arg:tt)*) => {
154        YError { 
155            code: INTERNAL_ERROR.to_string(), 
156            msg: format!($msg, $($arg)*),
157            module: module_path!().to_string(),
158            file: file!().to_string(), 
159            line: line!(),
160            trace: vec![],
161        }
162    };
163    ($code:literal:$msg:literal) => {
164        YError { 
165            code: $code.to_string(), 
166            msg: $msg.to_string(),
167            module: module_path!().to_string(),
168            file: file!().to_string(), 
169            line: line!(),
170            trace: vec![],
171        }
172    };
173    ($code:literal:$msg:literal, $($arg:tt)*) => {
174        YError { 
175            code: $code.to_string(), 
176            msg: format!($msg, $($arg)*),
177            module: module_path!().to_string(),
178            file: file!().to_string(), 
179            line: line!(),
180            trace: vec![],
181        }
182    };
183}