use std::error;
use std::fmt;
use std::panic::PanicHookInfo;
use std::str::Utf8Error;
#[derive(Debug, Clone)]
pub enum ConfigError {
UnknownType(i32),
StringDecode(Utf8Error),
}
impl fmt::Display for ConfigError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
ConfigError::UnknownType(type_) => {
write!(f, "unknown value ({}) for config enum", type_)
}
ConfigError::StringDecode(ref _e) => {
write!(f, "unable to convert config string to utf8")
}
}
}
}
impl error::Error for ConfigError {
fn description(&self) -> &str {
"error interpreting configuration values"
}
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match *self {
ConfigError::StringDecode(ref e) => Some(e),
ConfigError::UnknownType(_) => None,
}
}
}
#[derive(Debug, Clone)]
pub enum ArrayError {
NullPresent(usize, String),
TooLong(usize),
}
impl fmt::Display for ArrayError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
ArrayError::NullPresent(pos, ref s) => {
write!(f, "null encountered (pos: {}) in string: {}", pos, s)
}
ArrayError::TooLong(len) => write!(f, "length of {} is too long", len),
}
}
}
impl error::Error for ArrayError {
fn description(&self) -> &str {
"error generating array"
}
}
#[derive(Debug, Clone)]
pub enum ReceiveError {
Utf8 {
plugin: String,
field: &'static str,
err: Utf8Error,
},
Metadata {
plugin: String,
field: String,
msg: &'static str,
},
}
impl fmt::Display for ReceiveError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
ReceiveError::Utf8 {
ref plugin,
ref field,
..
} => {
write!(f, "plugin: {} submitted bad field: {}", plugin, field)
}
ReceiveError::Metadata {
ref plugin,
ref field,
msg,
} => {
write!(f, "plugin: {}, field: {}: {}", plugin, field, msg)
}
}
}
}
impl error::Error for ReceiveError {
fn description(&self) -> &str {
"error generating a value list"
}
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match *self {
ReceiveError::Utf8 { ref err, .. } => Some(err),
ReceiveError::Metadata { .. } => None,
}
}
}
#[derive(Debug, Clone)]
pub enum SubmitError {
Dispatch(i32),
Field {
name: &'static str,
err: ArrayError,
},
}
impl fmt::Display for SubmitError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
SubmitError::Dispatch(code) => {
write!(f, "plugin_dispatch_values returned an error: {}", code)
}
SubmitError::Field { name, .. } => write!(f, "error submitting {}", name),
}
}
}
impl error::Error for SubmitError {
fn description(&self) -> &str {
"error generating array"
}
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match *self {
SubmitError::Dispatch(_code) => None,
SubmitError::Field { ref err, .. } => Some(err),
}
}
}
#[derive(Clone, Copy, Debug)]
pub struct NotImplemented;
impl fmt::Display for NotImplemented {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "function is not implemented")
}
}
impl error::Error for NotImplemented {
fn description(&self) -> &str {
"function is not implemented"
}
}
#[derive(Clone, Debug)]
pub struct CacheRateError;
impl fmt::Display for CacheRateError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"unable to retrieve rate (see collectd logs for additional details)"
)
}
}
impl error::Error for CacheRateError {
fn description(&self) -> &str {
"unable to retrieve rate (see collectd logs for additional details)"
}
}
#[derive(Debug)]
pub enum FfiError<'a> {
PanicHook(&'a PanicHookInfo<'a>),
Panic,
Plugin(Box<dyn error::Error>),
Collectd(Box<dyn error::Error>),
UnknownSeverity(i32),
MultipleConfig,
Utf8(&'static str, Utf8Error),
}
impl fmt::Display for FfiError<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
FfiError::Collectd(_) => write!(f, "unexpected collectd behavior"),
FfiError::UnknownSeverity(severity) => {
write!(f, "unrecognized severity level: {}", severity)
}
FfiError::MultipleConfig => write!(f, "duplicate config section"),
FfiError::Panic => write!(f, "plugin panicked"),
FfiError::PanicHook(info) => {
write!(f, "plugin panicked: ")?;
if let Some(location) = info.location() {
write!(f, "({}: {}): ", location.file(), location.line(),)?;
}
if let Some(payload) = info.payload().downcast_ref::<&str>() {
write!(f, "{}", payload)?;
}
Ok(())
}
FfiError::Plugin(_) => write!(f, "plugin encountered an error"),
FfiError::Utf8(field, ref _e) => write!(f, "UTF-8 error for field: {}", field),
}
}
}
impl error::Error for FfiError<'_> {
fn description(&self) -> &str {
"collectd plugin error"
}
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match *self {
FfiError::Collectd(ref e) => Some(e.as_ref()),
FfiError::Plugin(ref e) => Some(e.as_ref()),
FfiError::Utf8(_field, ref e) => Some(e),
_ => None,
}
}
}