redgold_schema/observability/
errors.rs1use crate::helpers::easy_json::EasyJson;
2use crate::structs::{ErrorDetails, ErrorInfo, ResponseMetadata};
3use crate::message::Response;
4use crate::{structs, HashClear, RgResult};
5use log::{error, Level};
6use tracing::field::FieldSet;
7use tracing::{event, Event, Metadata};
8
9pub fn convert_log_level(level: String) -> log::Level {
10 match level.to_lowercase().as_str() {
11 "trace" => log::Level::Trace,
12 "debug" => log::Level::Debug,
13 "info" => log::Level::Info,
14 "warn" => log::Level::Warn,
15 "error" => log::Level::Error,
16 _ => log::Level::Error,
17 }
18}
19
20pub fn convert_trace_log_level(level: String) -> tracing::Level {
21 match level.to_lowercase().as_str() {
22 "trace" => tracing::Level::TRACE,
23 "debug" => tracing::Level::DEBUG,
24 "info" => tracing::Level::INFO,
25 "warn" => tracing::Level::WARN,
26 "error" => tracing::Level::ERROR,
27 _ => tracing::Level::ERROR,
28 }
29}
30
31pub trait Loggable<T> {
32 fn log_error(&self) -> RgResult<T>;
33}
34
35impl<T> Loggable<T> for RgResult<T> where T: Clone {
36 fn log_error(&self) -> RgResult<T> {
38 self.as_ref()
39 .map_err(|e| {
40 let e2 = e.clone();
41 if !e2.skip_logging {
42 let ser = e2.json_or();
43 if let Some(l) = e2.internal_log_level.as_ref(){
44 let _level = convert_trace_log_level(l.clone());
45 } else {
53 error!("{}", ser);
54 }
55 }
56 e.clone()
57 }).map(|t| t.clone())
58 }
59}
60
61impl ErrorInfo {
62 pub fn error_info<S: Into<String>>(message: S) -> ErrorInfo {
63 crate::error_info(message)
64 }
65 pub fn new(message: impl Into<String>) -> ErrorInfo {
66 crate::error_info(message.into())
67 }
68
69 pub fn response_metadata(self) -> ResponseMetadata {
70 ResponseMetadata {
71 success: false,
72 error_info: Some(self),
73 task_local_details: vec![],
74 request_id: None,
75 trace_id: None,
76 }
77 }
78 pub fn enhance(self, message: impl Into<String>) -> ErrorInfo {
79 let mut e = self;
80 e.message = format!("{} {} ", e.message, message.into());
81 e
82 }
83 pub fn with_detail(&mut self, k: impl Into<String>, v: impl Into<String>) {
84 let mut ed = ErrorDetails::default();
85 ed.detail = v.into();
86 ed.detail_name = k.into();
87 self.details.push(ed);
88 }
89 pub fn with_code(&mut self, v: structs::ErrorCode) {
90 self.code = v as i32;
91 }
92
93}
94
95impl HashClear for ErrorInfo {
96 fn hash_clear(&mut self) {
97
98 }
99}
100
101pub trait EnhanceErrorInfo<T> {
102 fn add(self, message: impl Into<String>) -> RgResult<T>;
103 fn mark_abort(self) -> RgResult<T>;
104 fn bubble_abort(self) -> RgResult<RgResult<T>>;
105 fn with_code(self, v: structs::ErrorCode) -> RgResult<T>;
106 fn with_detail(self, k: impl Into<String>, v: impl Into<String>) -> RgResult<T>;
107 fn with_detail_fn<F>(self, k: impl Into<String>, v: impl Fn() -> F) -> RgResult<T>
108 where F: Into<String> + Sized;
109 fn mark_skip_log(self) -> RgResult<T>;
110 fn level(self, l: Level) -> RgResult<T>;
111}
112
113impl<T> EnhanceErrorInfo<T> for RgResult<T> {
114 fn add(self, message: impl Into<String>) -> RgResult<T> {
115 self.map_err(|e| e.enhance(message))
116 }
117 fn mark_abort(self) -> RgResult<T> {
118 self.map_err(|mut e| {
119 e.abort = true;
120 e
121 })
122 }
123 fn bubble_abort(self) -> RgResult<RgResult<T>> {
124 match self {
125 Ok(r) => {Ok(Ok(r))}
126 Err(e) => {
127 if !e.abort {
128 Ok(Err(e))
129 } else {
130 Err(e)
131 }
132 }
133 }
134 }
135 fn with_code(self, v: structs::ErrorCode) -> RgResult<T> {
136 self.map_err(|mut e| {
137 e.with_code(v);
138 e
139 })
140 }
141 fn with_detail(self, k: impl Into<String>, v: impl Into<String>) -> RgResult<T> {
142 self.map_err(|mut e| {
143 e.with_detail(k, v);
144 e
145 })
146 }
147
148
149 fn with_detail_fn<F>(self, k: impl Into<String>, v: impl Fn() -> F) -> RgResult<T>
150 where F: Into<String> + Sized{
151 self.map_err(|mut e| {
152 let v = v().into();
153 e.with_detail(k, v);
154 e
155 })
156 }
157
158 fn mark_skip_log(self) -> RgResult<T> {
159 self.map_err(|mut e| {
160 e.skip_logging = true;
161 e
162 })
163 }
164
165 fn level(self, l: Level) -> RgResult<T> {
166 self.map_err(|mut e| {
167 e.internal_log_level = Some(l.to_string());
168 e
169 })
170 }
171
172}