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::de;
13use bson::document::ValueAccessError;
14
15#[derive(Debug, Clone)]
20pub enum MetricParseError {
21 Io(Arc<io::Error>),
23
24 BsonDeserialzation(de::Error),
26
27 FieldAccess(KeyAccessError),
29
30 UnknownDocumentKind(i32),
32
33 MetricCountMismatch,
36
37 MetricTimestampNotFound {
39 name: Arc<str>,
41 },
42
43 IntConversion(TryFromIntError),
46}
47
48impl Display for MetricParseError {
49 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
50 let parse_error = "metric parse error:";
51
52 match self {
53 MetricParseError::Io(error) => write!(f, "{parse_error} I/O error: {error}"),
54 MetricParseError::BsonDeserialzation(error) => {
55 write!(f, "{parse_error} BSON deserialization error: {error}")
56 }
57 MetricParseError::FieldAccess(error) => write!(
58 f,
59 "{parse_error} could not read the document field: {error}"
60 ),
61 MetricParseError::MetricCountMismatch => write!(
62 f,
63 "{parse_error} the amount of metrics in the reference document is different than the amount of metric samples"
64 ),
65 MetricParseError::MetricTimestampNotFound { name } => write!(
66 f,
67 "{parse_error} the metric timestamps for the {name} metric could not be found",
68 ),
69 MetricParseError::IntConversion(error) => {
70 write!(f, "{parse_error} could not parse integer: {error}")
71 }
72 MetricParseError::UnknownDocumentKind(value) => {
73 write!(f, "{parse_error} unknonw document type: {value}")
74 }
75 }
76 }
77}
78
79impl Error for MetricParseError {
80 fn source(&self) -> Option<&(dyn Error + 'static)> {
81 match self {
82 MetricParseError::Io(error) => Some(error),
83 MetricParseError::BsonDeserialzation(error) => Some(error),
84 MetricParseError::FieldAccess(error) => Some(error),
85 MetricParseError::MetricCountMismatch => None,
86 MetricParseError::MetricTimestampNotFound { .. } => None,
87 MetricParseError::IntConversion(error) => Some(error),
88 MetricParseError::UnknownDocumentKind(_) => None,
89 }
90 }
91}
92
93impl From<io::Error> for MetricParseError {
94 fn from(error: io::Error) -> Self {
95 MetricParseError::Io(Arc::new(error))
96 }
97}
98
99impl From<de::Error> for MetricParseError {
100 fn from(error: de::Error) -> Self {
101 MetricParseError::BsonDeserialzation(error)
102 }
103}
104
105impl From<TryFromIntError> for MetricParseError {
106 fn from(error: TryFromIntError) -> Self {
107 MetricParseError::IntConversion(error)
108 }
109}
110
111impl From<KeyAccessError> for MetricParseError {
112 fn from(error: KeyAccessError) -> Self {
113 MetricParseError::FieldAccess(error)
114 }
115}
116
117#[derive(Debug, Clone)]
119pub enum KeyAccessError {
120 KeyNotFound {
122 key: String,
124 },
125
126 UnexpectedKeyType {
128 key: String,
130 },
131
132 AccessError {
134 key: String,
136
137 error: String,
139 },
140}
141
142impl Display for KeyAccessError {
143 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
144 let key_access_error = "key access error:";
145 match *self {
146 KeyAccessError::KeyNotFound { ref key } => {
147 write!(
148 f,
149 "{key_access_error} could not find the field with the {key} key",
150 )
151 }
152 KeyAccessError::UnexpectedKeyType { ref key } => write!(
153 f,
154 "{key_access_error} the field with {key} key was found, but not with the expected type",
155 ),
156 KeyAccessError::AccessError { ref key, ref error } => {
157 write!(
158 f,
159 "{key_access_error} could not access the field value with the {key} key. {error}",
160 )
161 }
162 }
163 }
164}
165
166impl Error for KeyAccessError {}
167
168pub(crate) trait ValueAccessResultExt<T> {
169 fn map_value_access_err(self, key: &str) -> Result<T, KeyAccessError>;
170}
171
172impl<T> ValueAccessResultExt<T> for Result<T, ValueAccessError> {
173 fn map_value_access_err(self, key: &str) -> Result<T, KeyAccessError> {
174 self.map_err(|error| match error {
175 ValueAccessError::NotPresent => KeyAccessError::KeyNotFound {
176 key: key.to_owned(),
177 },
178 ValueAccessError::UnexpectedType => KeyAccessError::UnexpectedKeyType {
179 key: key.to_owned(),
180 },
181 e => KeyAccessError::AccessError {
182 key: key.to_owned(),
183 error: e.to_string(),
184 },
185 })
186 }
187}