use config_file_handler;
use futures::sync::mpsc::SendError;
use maidsafe_utilities::serialisation::SerialisationError;
use routing::{ClientError, InterfaceError, RoutingError};
use routing::messaging;
use self_encryption::SelfEncryptionError;
use self_encryption_storage::SelfEncryptionStorageError;
use std::error::Error;
use std::fmt::{self, Debug, Display, Formatter};
use std::io;
use std::sync::mpsc;
#[cfg_attr(feature = "cargo-clippy", allow(large_enum_variant))]
pub enum CoreError {
EncodeDecodeError(SerialisationError),
AsymmetricDecipherFailure,
SymmetricDecipherFailure,
ReceivedUnexpectedData,
ReceivedUnexpectedEvent,
VersionCacheMiss,
RootDirectoryExists,
RandomDataGenerationFailure,
OperationForbidden,
Unexpected(String),
RoutingError(RoutingError),
RoutingInterfaceError(InterfaceError),
RoutingClientError(ClientError),
UnsupportedSaltSizeForPwHash,
UnsuccessfulPwHash,
OperationAborted,
MpidMessagingError(messaging::Error),
SelfEncryption(SelfEncryptionError<SelfEncryptionStorageError>),
RequestTimeout,
ConfigError(config_file_handler::Error),
IoError(io::Error),
}
impl<'a> From<&'a str> for CoreError {
fn from(error: &'a str) -> CoreError {
CoreError::Unexpected(error.to_string())
}
}
impl From<String> for CoreError {
fn from(error: String) -> CoreError {
CoreError::Unexpected(error)
}
}
impl<T> From<SendError<T>> for CoreError {
fn from(error: SendError<T>) -> CoreError {
CoreError::from(format!("Couldn't send message to the channel: {}", error))
}
}
impl From<SerialisationError> for CoreError {
fn from(error: SerialisationError) -> CoreError {
CoreError::EncodeDecodeError(error)
}
}
impl From<RoutingError> for CoreError {
fn from(error: RoutingError) -> CoreError {
CoreError::RoutingError(error)
}
}
impl From<InterfaceError> for CoreError {
fn from(error: InterfaceError) -> CoreError {
CoreError::RoutingInterfaceError(error)
}
}
impl From<ClientError> for CoreError {
fn from(error: ClientError) -> CoreError {
CoreError::RoutingClientError(error)
}
}
impl From<mpsc::RecvError> for CoreError {
fn from(_: mpsc::RecvError) -> CoreError {
CoreError::OperationAborted
}
}
impl From<messaging::Error> for CoreError {
fn from(error: messaging::Error) -> CoreError {
CoreError::MpidMessagingError(error)
}
}
impl From<SelfEncryptionError<SelfEncryptionStorageError>> for CoreError {
fn from(error: SelfEncryptionError<SelfEncryptionStorageError>) -> CoreError {
CoreError::SelfEncryption(error)
}
}
impl From<config_file_handler::Error> for CoreError {
fn from(error: config_file_handler::Error) -> CoreError {
CoreError::ConfigError(error)
}
}
impl From<io::Error> for CoreError {
fn from(error: io::Error) -> CoreError {
CoreError::IoError(error)
}
}
impl Debug for CoreError {
fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
write!(formatter, "{} - ", self.description())?;
match *self {
CoreError::EncodeDecodeError(ref error) => {
write!(formatter, "CoreError::EncodeDecodeError -> {:?}", error)
}
CoreError::AsymmetricDecipherFailure => {
write!(formatter, "CoreError::AsymmetricDecipherFailure")
}
CoreError::SymmetricDecipherFailure => {
write!(formatter, "CoreError::SymmetricDecipherFailure")
}
CoreError::ReceivedUnexpectedData => {
write!(formatter, "CoreError::ReceivedUnexpectedData")
}
CoreError::ReceivedUnexpectedEvent => {
write!(formatter, "CoreError::ReceivedUnexpectedEvent")
}
CoreError::VersionCacheMiss => write!(formatter, "CoreError::VersionCacheMiss"),
CoreError::RootDirectoryExists => write!(formatter, "CoreError::RootDirectoryExists"),
CoreError::RandomDataGenerationFailure => {
write!(formatter, "CoreError::RandomDataGenerationFailure")
}
CoreError::OperationForbidden => write!(formatter, "CoreError::OperationForbidden"),
CoreError::Unexpected(ref error) => {
write!(formatter, "CoreError::Unexpected::{{{:?}}}", error)
}
CoreError::RoutingError(ref error) => {
write!(formatter, "CoreError::RoutingError -> {:?}", error)
}
CoreError::RoutingInterfaceError(ref error) => {
write!(formatter, "CoreError::RoutingInterfaceError -> {:?}", error)
}
CoreError::RoutingClientError(ref error) => {
write!(formatter, "CoreError::RoutingClientError -> {:?}", error)
}
CoreError::UnsupportedSaltSizeForPwHash => {
write!(formatter, "CoreError::UnsupportedSaltSizeForPwHash")
}
CoreError::UnsuccessfulPwHash => write!(formatter, "CoreError::UnsuccessfulPwHash"),
CoreError::OperationAborted => write!(formatter, "CoreError::OperationAborted"),
CoreError::MpidMessagingError(ref error) => {
write!(formatter, "CoreError::MpidMessagingError -> {:?}", error)
}
CoreError::SelfEncryption(ref error) => {
write!(formatter, "CoreError::SelfEncryption -> {:?}", error)
}
CoreError::RequestTimeout => write!(formatter, "CoreError::RequestTimeout"),
CoreError::ConfigError(ref error) => {
write!(formatter, "CoreError::ConfigError -> {:?}", error)
}
CoreError::IoError(ref error) => write!(formatter, "CoreError::IoError -> {:?}", error),
}
}
}
impl Display for CoreError {
fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
match *self {
CoreError::EncodeDecodeError(ref error) => {
write!(
formatter,
"Error while serialising/deserialising: {}",
error
)
}
CoreError::AsymmetricDecipherFailure => {
write!(formatter, "Asymmetric decryption failed")
}
CoreError::SymmetricDecipherFailure => write!(formatter, "Symmetric decryption failed"),
CoreError::ReceivedUnexpectedData => write!(formatter, "Received unexpected data"),
CoreError::ReceivedUnexpectedEvent => write!(formatter, "Received unexpected event"),
CoreError::VersionCacheMiss => {
write!(formatter, "No such data found in local version cache")
}
CoreError::RootDirectoryExists => {
write!(
formatter,
"Cannot overwrite a root directory if it already exists"
)
}
CoreError::RandomDataGenerationFailure => {
write!(formatter, "Unable to obtain generator for random data")
}
CoreError::OperationForbidden => write!(formatter, "Forbidden operation requested"),
CoreError::Unexpected(ref error) => write!(formatter, "Unexpected: {}", error),
CoreError::RoutingError(ref error) => {
write!(formatter, "Routing internal error: {:?}", error)
}
CoreError::RoutingInterfaceError(ref error) => {
write!(formatter, "Routing interface error -> {:?}", error)
}
CoreError::RoutingClientError(ref error) => {
write!(formatter, "Routing client error -> {}", error)
}
CoreError::UnsupportedSaltSizeForPwHash => {
write!(
formatter,
"Unable to pack into or operate with size of Salt"
)
}
CoreError::UnsuccessfulPwHash => {
write!(
formatter,
"Unable to complete computation for password hashing"
)
}
CoreError::OperationAborted => write!(formatter, "Blocking operation was cancelled"),
CoreError::MpidMessagingError(ref error) => {
write!(formatter, "Mpid messaging error: {}", error)
}
CoreError::SelfEncryption(ref error) => {
write!(formatter, "Self-encryption error: {}", error)
}
CoreError::RequestTimeout => write!(formatter, "CoreError::RequestTimeout"),
CoreError::ConfigError(ref error) => write!(formatter, "Config file error: {}", error),
CoreError::IoError(ref error) => write!(formatter, "Io error: {}", error),
}
}
}
impl Error for CoreError {
fn description(&self) -> &str {
match *self {
CoreError::EncodeDecodeError(_) => "Serialisation error",
CoreError::AsymmetricDecipherFailure => "Asymmetric decryption failure",
CoreError::SymmetricDecipherFailure => "Symmetric decryption failure",
CoreError::ReceivedUnexpectedData => "Received unexpected data",
CoreError::ReceivedUnexpectedEvent => "Received unexpected event",
CoreError::VersionCacheMiss => "Version cache miss",
CoreError::RootDirectoryExists => "Root directory already exists",
CoreError::RandomDataGenerationFailure => "Cannot obtain RNG",
CoreError::OperationForbidden => "Operation forbidden",
CoreError::Unexpected(_) => "Unexpected error",
CoreError::RoutingError(_) => "Routing internal error",
CoreError::RoutingClientError(ref error) => error.description(),
CoreError::RoutingInterfaceError(_) => "Routing interface error",
CoreError::UnsupportedSaltSizeForPwHash => "Unsupported size of salt",
CoreError::UnsuccessfulPwHash => "Failed while password hashing",
CoreError::OperationAborted => "Operation aborted",
CoreError::MpidMessagingError(_) => "Mpid messaging error",
CoreError::SelfEncryption(ref error) => error.description(),
CoreError::RequestTimeout => "Request has timed out",
CoreError::ConfigError(ref error) => error.description(),
CoreError::IoError(ref error) => error.description(),
}
}
fn cause(&self) -> Option<&Error> {
match *self {
CoreError::EncodeDecodeError(ref err) => Some(err),
CoreError::MpidMessagingError(ref err) => Some(err),
CoreError::RoutingClientError(ref err) => Some(err),
CoreError::SelfEncryption(ref err) => Some(err),
_ => None,
}
}
}
#[cfg(test)]
mod tests {
}