1use std::error;
2use std::fmt;
3use std::panic::PanicInfo;
4use std::str::Utf8Error;
5
6#[derive(Debug, Clone)]
8pub enum ConfigError {
9 UnknownType(i32),
11
12 StringDecode(Utf8Error),
14}
15
16impl fmt::Display for ConfigError {
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18 match *self {
19 ConfigError::UnknownType(type_) => {
20 write!(f, "unknown value ({}) for config enum", type_)
21 }
22 ConfigError::StringDecode(ref _e) => {
23 write!(f, "unable to convert config string to utf8")
24 }
25 }
26 }
27}
28
29impl error::Error for ConfigError {
30 fn description(&self) -> &str {
31 "error interpreting configuration values"
32 }
33
34 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
35 match *self {
36 ConfigError::StringDecode(ref e) => Some(e),
37 ConfigError::UnknownType(_) => None,
38 }
39 }
40}
41
42#[derive(Debug, Clone)]
45pub enum ArrayError {
46 NullPresent(usize, String),
48
49 TooLong(usize),
51}
52
53impl fmt::Display for ArrayError {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 match *self {
56 ArrayError::NullPresent(pos, ref s) => {
57 write!(f, "null encountered (pos: {}) in string: {}", pos, s)
58 }
59 ArrayError::TooLong(len) => write!(f, "length of {} is too long", len),
60 }
61 }
62}
63
64impl error::Error for ArrayError {
65 fn description(&self) -> &str {
66 "error generating array"
67 }
68}
69
70#[derive(Debug, Clone)]
72pub enum ReceiveError {
73 Utf8 {
75 plugin: String,
77
78 field: &'static str,
80
81 err: Utf8Error,
83 },
84 Metadata {
85 plugin: String,
87
88 field: String,
90
91 msg: &'static str,
93 },
94}
95
96impl fmt::Display for ReceiveError {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 match *self {
99 ReceiveError::Utf8 {
100 ref plugin,
101 ref field,
102 ..
103 } => {
104 write!(f, "plugin: {} submitted bad field: {}", plugin, field)
105 }
106 ReceiveError::Metadata {
107 ref plugin,
108 ref field,
109 msg,
110 } => {
111 write!(f, "plugin: {}, field: {}: {}", plugin, field, msg)
112 }
113 }
114 }
115}
116
117impl error::Error for ReceiveError {
118 fn description(&self) -> &str {
119 "error generating a value list"
120 }
121
122 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
123 match *self {
124 ReceiveError::Utf8 { ref err, .. } => Some(err),
125 ReceiveError::Metadata { .. } => None,
126 }
127 }
128}
129
130#[derive(Debug, Clone)]
132pub enum SubmitError {
133 Dispatch(i32),
135
136 Field {
138 name: &'static str,
140
141 err: ArrayError,
143 },
144}
145
146impl fmt::Display for SubmitError {
147 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
148 match *self {
149 SubmitError::Dispatch(code) => {
150 write!(f, "plugin_dispatch_values returned an error: {}", code)
151 }
152 SubmitError::Field { name, .. } => write!(f, "error submitting {}", name),
153 }
154 }
155}
156
157impl error::Error for SubmitError {
158 fn description(&self) -> &str {
159 "error generating array"
160 }
161
162 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
163 match *self {
164 SubmitError::Dispatch(_code) => None,
165 SubmitError::Field { ref err, .. } => Some(err),
166 }
167 }
168}
169
170#[derive(Clone, Copy, Debug)]
173pub struct NotImplemented;
174
175impl fmt::Display for NotImplemented {
176 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177 write!(f, "function is not implemented")
178 }
179}
180
181impl error::Error for NotImplemented {
182 fn description(&self) -> &str {
183 "function is not implemented"
184 }
185}
186
187#[derive(Clone, Debug)]
189pub struct CacheRateError;
190
191impl fmt::Display for CacheRateError {
192 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
193 write!(
194 f,
195 "unable to retrieve rate (see collectd logs for additional details)"
196 )
197 }
198}
199
200impl error::Error for CacheRateError {
201 fn description(&self) -> &str {
202 "unable to retrieve rate (see collectd logs for additional details)"
203 }
204}
205
206#[derive(Debug)]
208pub enum FfiError<'a> {
209 PanicHook(&'a PanicInfo<'a>),
211
212 Panic,
215
216 Plugin(Box<dyn error::Error>),
219
220 Collectd(Box<dyn error::Error>),
222
223 UnknownSeverity(i32),
225
226 MultipleConfig,
228
229 Utf8(&'static str, Utf8Error),
231}
232
233impl<'a> fmt::Display for FfiError<'a> {
234 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
235 match *self {
236 FfiError::Collectd(_) => write!(f, "unexpected collectd behavior"),
237 FfiError::UnknownSeverity(severity) => {
238 write!(f, "unrecognized severity level: {}", severity)
239 }
240 FfiError::MultipleConfig => write!(f, "duplicate config section"),
241 FfiError::Panic => write!(f, "plugin panicked"),
242 FfiError::PanicHook(info) => {
243 write!(f, "plugin panicked: ")?;
244 if let Some(location) = info.location() {
245 write!(f, "({}: {}): ", location.file(), location.line(),)?;
246 }
247
248 if let Some(payload) = info.payload().downcast_ref::<&str>() {
249 write!(f, "{}", payload)?;
250 }
251
252 Ok(())
253 }
254 FfiError::Plugin(_) => write!(f, "plugin encountered an error"),
255 FfiError::Utf8(field, ref _e) => write!(f, "UTF-8 error for field: {}", field),
256 }
257 }
258}
259
260impl<'a> error::Error for FfiError<'a> {
261 fn description(&self) -> &str {
262 "collectd plugin error"
263 }
264
265 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
266 match *self {
267 FfiError::Collectd(ref e) => Some(e.as_ref()),
268 FfiError::Plugin(ref e) => Some(e.as_ref()),
269 FfiError::Utf8(_field, ref e) => Some(e),
270 _ => None,
271 }
272 }
273}