1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
//! Defines fundamental types used throughout the DrMem codebase.
use std::fmt;
use tokio::sync::{mpsc, oneshot};
/// Enumerates all the errors that can be reported in DrMem. Authors
/// for new drivers or storage backends should try to map their errors
/// into one of these values. If no current value is appropriate, a
/// new one could be added (requiring a new release of this crate) but
/// make sure the new error code is generic enough that it may be
/// useful for other drivers or backends. For instance, don't add an
/// error value that is specific to Redis. Add a more general value
/// and use the associated description string to explain the details.
#[derive(Debug, PartialEq, Eq)]
pub enum Error {
/// Returned whenever a resource cannot be found.
NotFound,
/// A resource is already in use.
InUse,
/// The device name is already registered to another driver.
DeviceDefined(String),
/// Reported when the peer of a communication channel has closed
/// its handle.
MissingPeer(String),
/// A type mismatch is preventing the operation from continuing.
TypeError,
/// An invalid value was provided.
InvArgument(String),
/// Returned when a communication error occurred with the backend
/// database. Each backend will have its own recommendations on
/// how to recover.
DbCommunicationError,
/// Communication was disrupted due to one end not following a
/// protocol.
ProtocolError(String),
/// The requested operation cannot complete because the process
/// hasn't provided proper authentication credentials.
AuthenticationError,
/// An operation didn't complete in a timely fashion.
TimeoutError,
/// The requested operation couldn't complete. The description
/// field will have more information for the user.
OperationError,
/// A bad parameter was given in a configuration or a
/// configuration was missing a required parameter.
BadConfig(String),
/// There was a problem parsing a string. The associated string
/// will describe how the parsing failed.
ParseError(String),
/// A dependent library introduced a new error that hasn't been
/// properly mapped in DrMem. This needs to be reported as a bug.
UnknownError,
}
impl std::error::Error for Error {}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::NotFound => write!(f, "item not found"),
Error::InUse => write!(f, "item is in use"),
Error::DeviceDefined(name) => {
write!(f, "device {} is already defined", &name)
}
Error::MissingPeer(detail) => {
write!(f, "{} is missing peer", detail)
}
Error::TypeError => write!(f, "incorrect type"),
Error::InvArgument(s) => write!(f, "{}", s),
Error::DbCommunicationError => {
write!(f, "db communication error")
}
Error::ProtocolError(v) => write!(f, "protocol error: {}", &v),
Error::AuthenticationError => write!(f, "permission error"),
Error::TimeoutError => write!(f, "timeout"),
Error::OperationError => {
write!(f, "couldn't complete operation")
}
Error::BadConfig(v) => write!(f, "config error: {}", &v),
Error::ParseError(v) => write!(f, "parse error: {}", &v),
Error::UnknownError => write!(f, "unhandled error"),
}
}
}
// Defining these trait implementations allows any code that sends
// requests over an `mpsc` channel and expects the reply in a
// `oneshot` to easily translate the channel errors into a DrMem
// error.
impl<T> From<mpsc::error::SendError<T>> for Error {
fn from(_error: mpsc::error::SendError<T>) -> Self {
Error::MissingPeer(String::from("request channel is closed"))
}
}
impl From<oneshot::error::RecvError> for Error {
fn from(_error: oneshot::error::RecvError) -> Self {
Error::MissingPeer(String::from("request dropped"))
}
}
pub mod device;