mprobe_diagnostics/
error.rs1use std::convert::From;
4use std::error::Error;
5use std::fmt;
6use std::fmt::Display;
7use std::fmt::Formatter;
8use std::io;
9use std::num::TryFromIntError;
10use std::sync::Arc;
11
12use bson::error::Error as BsonError;
13use bson::error::ErrorKind as BsonErrorKind;
14use bson::error::ValueAccessErrorKind;
15
16#[derive(Debug, Clone)]
21pub enum MetricParseError {
22 Io(Arc<io::Error>),
24
25 BsonDeserialzation(BsonError),
27
28 FieldAccess(KeyAccessError),
30
31 UnknownDocumentKind(i32),
33
34 MetricCountMismatch,
37
38 MetricTimestampNotFound {
40 name: Arc<str>,
42 },
43
44 IntConversion(TryFromIntError),
47}
48
49impl Display for MetricParseError {
50 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
51 let parse_error = "metric parse error:";
52
53 match self {
54 MetricParseError::Io(error) => write!(f, "{parse_error} I/O error: {error}"),
55 MetricParseError::BsonDeserialzation(error) => {
56 write!(f, "{parse_error} BSON deserialization error: {error}")
57 }
58 MetricParseError::FieldAccess(error) => write!(
59 f,
60 "{parse_error} could not read the document field: {error}"
61 ),
62 MetricParseError::MetricCountMismatch => write!(
63 f,
64 "{parse_error} the amount of metrics in the reference document is different than the amount of metric samples"
65 ),
66 MetricParseError::MetricTimestampNotFound { name } => write!(
67 f,
68 "{parse_error} the metric timestamps for the {name} metric could not be found",
69 ),
70 MetricParseError::IntConversion(error) => {
71 write!(f, "{parse_error} could not parse integer: {error}")
72 }
73 MetricParseError::UnknownDocumentKind(value) => {
74 write!(f, "{parse_error} unknonw document type: {value}")
75 }
76 }
77 }
78}
79
80impl Error for MetricParseError {
81 fn source(&self) -> Option<&(dyn Error + 'static)> {
82 match self {
83 MetricParseError::Io(error) => Some(error),
84 MetricParseError::BsonDeserialzation(error) => Some(error),
85 MetricParseError::FieldAccess(error) => Some(error),
86 MetricParseError::MetricCountMismatch => None,
87 MetricParseError::MetricTimestampNotFound { .. } => None,
88 MetricParseError::IntConversion(error) => Some(error),
89 MetricParseError::UnknownDocumentKind(_) => None,
90 }
91 }
92}
93
94impl From<io::Error> for MetricParseError {
95 fn from(error: io::Error) -> Self {
96 MetricParseError::Io(Arc::new(error))
97 }
98}
99
100impl From<BsonError> for MetricParseError {
101 fn from(error: BsonError) -> Self {
102 MetricParseError::BsonDeserialzation(error)
103 }
104}
105
106impl From<TryFromIntError> for MetricParseError {
107 fn from(error: TryFromIntError) -> Self {
108 MetricParseError::IntConversion(error)
109 }
110}
111
112impl From<KeyAccessError> for MetricParseError {
113 fn from(error: KeyAccessError) -> Self {
114 MetricParseError::FieldAccess(error)
115 }
116}
117
118#[derive(Debug, Clone)]
120pub enum KeyAccessError {
121 KeyNotFound {
123 key: String,
125 },
126
127 UnexpectedKeyType {
129 key: String,
131 },
132
133 AccessError {
135 key: String,
137
138 error: String,
140 },
141}
142
143impl Display for KeyAccessError {
144 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
145 let key_access_error = "key access error:";
146 match *self {
147 KeyAccessError::KeyNotFound { ref key } => {
148 write!(
149 f,
150 "{key_access_error} could not find the field with the {key} key"
151 )
152 }
153 KeyAccessError::UnexpectedKeyType { ref key } => write!(
154 f,
155 "{key_access_error} the field with {key} key was found, but not with the expected type"
156 ),
157 KeyAccessError::AccessError { ref key, ref error } => {
158 write!(
159 f,
160 "{key_access_error} could not access the field value with the {key} key. {error}"
161 )
162 }
163 }
164 }
165}
166
167impl Error for KeyAccessError {}
168
169pub(crate) trait ValueAccessResultExt<T> {
170 fn map_value_access_err(self, key: &str) -> Result<T, KeyAccessError>;
171}
172
173impl<T> ValueAccessResultExt<T> for Result<T, BsonError> {
174 fn map_value_access_err(self, key: &str) -> Result<T, KeyAccessError> {
175 self.map_err(|error| match error.kind {
176 BsonErrorKind::ValueAccess { kind, .. } => match kind {
177 ValueAccessErrorKind::NotPresent { .. } => KeyAccessError::KeyNotFound {
178 key: key.to_owned(),
179 },
180 ValueAccessErrorKind::UnexpectedType { .. } => KeyAccessError::UnexpectedKeyType {
181 key: key.to_owned(),
182 },
183 e => KeyAccessError::AccessError {
184 key: key.to_owned(),
185 error: e.to_string(),
186 },
187 },
188 _ => KeyAccessError::AccessError {
189 key: key.to_owned(),
190 error: format!("{error}"),
191 },
192 })
193 }
194}