use bincode::Error as SerialisationError;
use ffi_utils::StringError;
use futures::channel::mpsc::SendError;
use safe_core::ipc::IpcError;
use safe_core::nfs::NfsError;
use safe_core::{CoreError, SelfEncryptionStorageError};
use safe_nd::Error as SndError;
use self_encryption::SelfEncryptionError;
use std::ffi::NulError;
use std::fmt::{self, Display, Formatter};
use std::io::Error as IoError;
use std::str::Utf8Error;
use std::sync::mpsc::{RecvError, RecvTimeoutError};
use threshold_crypto::error::FromBytesError;
#[derive(Debug)]
#[allow(clippy::large_enum_variant)]
pub enum AppError {
CoreError(CoreError),
SndError(SndError),
IpcError(IpcError),
NfsError(NfsError),
EncodeDecodeError,
OperationForbidden,
NoSuchContainer(String),
InvalidFileMode,
UnregisteredClientAccess,
InvalidCipherOptHandle,
InvalidEncryptPubKeyHandle,
InvalidEncryptSecKeyHandle,
InvalidMDataEntriesHandle,
InvalidMDataEntryActionsHandle,
InvalidMDataPermissionsHandle,
InvalidSelfEncryptorHandle,
InvalidSignPubKeyHandle,
InvalidSignSecKeyHandle,
InvalidPubKeyHandle,
InvalidFileContextHandle,
SelfEncryption(SelfEncryptionError<SelfEncryptionStorageError>),
InvalidSelfEncryptorReadOffsets,
IoError(IoError),
Unexpected(String),
}
impl Display for AppError {
fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
match *self {
Self::CoreError(ref error) => write!(formatter, "Core error: {}", error),
Self::SndError(ref error) => write!(formatter, "Safe ND error: {}", error),
Self::IpcError(ref error) => write!(formatter, "IPC error: {:?}", error),
Self::NfsError(ref error) => write!(formatter, "NFS error: {}", error),
Self::EncodeDecodeError => write!(formatter, "Serialisation error"),
Self::OperationForbidden => write!(formatter, "Forbidden operation"),
Self::NoSuchContainer(ref name) => {
write!(formatter, "'{}' not found in the access container", name)
}
Self::InvalidCipherOptHandle => write!(formatter, "Invalid CipherOpt handle"),
Self::InvalidFileMode => write!(
formatter,
"Invalid file mode (e.g. trying to write when file is opened for reading only)"
),
Self::UnregisteredClientAccess => write!(
formatter,
"Tried to access a client key from an unregistered client",
),
Self::InvalidEncryptPubKeyHandle => {
write!(formatter, "Invalid encrypt (threshold_crypto) key handle")
}
Self::InvalidMDataEntriesHandle => {
write!(formatter, "Invalid MutableData entries handle")
}
Self::InvalidMDataEntryActionsHandle => {
write!(formatter, "Invalid MutableData entry actions handle")
}
Self::InvalidMDataPermissionsHandle => {
write!(formatter, "Invalid MutableData permissions handle")
}
Self::InvalidSelfEncryptorHandle => write!(formatter, "Invalid Self Encryptor handle"),
Self::InvalidSignPubKeyHandle => write!(formatter, "Invalid sign public key handle"),
Self::InvalidSignSecKeyHandle => write!(formatter, "Invalid sign secret key handle"),
Self::InvalidPubKeyHandle => write!(formatter, "Invalid public key handle"),
Self::InvalidEncryptSecKeyHandle => write!(formatter, "Invalid secret key handle"),
Self::InvalidFileContextHandle => write!(formatter, "Invalid file context handle"),
Self::SelfEncryption(ref error) => {
write!(formatter, "Self-encryption error: {}", error)
}
Self::InvalidSelfEncryptorReadOffsets => write!(
formatter,
"Invalid offsets (from-position \
and length combination) provided for \
reading form SelfEncryptor. Would have \
probably caused an overflow."
),
Self::IoError(ref error) => write!(formatter, "I/O error: {}", error),
Self::Unexpected(ref error) => {
write!(formatter, "Unexpected (probably a logic error): {}", error)
}
}
}
}
impl From<CoreError> for AppError {
fn from(err: CoreError) -> Self {
match err {
CoreError::Unexpected(reason) => Self::Unexpected(reason),
_ => Self::CoreError(err),
}
}
}
impl From<IpcError> for AppError {
fn from(err: IpcError) -> Self {
match err {
IpcError::EncodeDecodeError => Self::EncodeDecodeError,
IpcError::Unexpected(reason) => Self::Unexpected(reason),
_ => Self::IpcError(err),
}
}
}
impl From<NfsError> for AppError {
fn from(err: NfsError) -> Self {
match err {
NfsError::CoreError(err) => Self::CoreError(err),
NfsError::EncodeDecodeError(_) => Self::EncodeDecodeError,
NfsError::SelfEncryption(err) => Self::SelfEncryption(err),
NfsError::Unexpected(reason) => Self::Unexpected(reason),
_ => Self::NfsError(err),
}
}
}
impl From<SerialisationError> for AppError {
fn from(_err: SerialisationError) -> Self {
Self::EncodeDecodeError
}
}
impl From<Utf8Error> for AppError {
fn from(_err: Utf8Error) -> Self {
Self::EncodeDecodeError
}
}
impl From<StringError> for AppError {
fn from(_err: StringError) -> Self {
Self::EncodeDecodeError
}
}
impl From<SelfEncryptionError<SelfEncryptionStorageError>> for AppError {
fn from(err: SelfEncryptionError<SelfEncryptionStorageError>) -> Self {
Self::SelfEncryption(err)
}
}
impl From<IoError> for AppError {
fn from(err: IoError) -> Self {
Self::IoError(err)
}
}
impl From<SndError> for AppError {
fn from(error: SndError) -> Self {
Self::SndError(error)
}
}
impl<'a> From<&'a str> for AppError {
fn from(s: &'a str) -> Self {
Self::Unexpected(s.to_string())
}
}
impl From<String> for AppError {
fn from(s: String) -> Self {
Self::Unexpected(s)
}
}
impl From<SendError> for AppError {
fn from(err: SendError) -> Self {
Self::from(err.to_string())
}
}
impl From<NulError> for AppError {
fn from(err: NulError) -> Self {
Self::from(err.to_string())
}
}
impl From<RecvError> for AppError {
fn from(err: RecvError) -> Self {
Self::from(err.to_string())
}
}
impl From<RecvTimeoutError> for AppError {
fn from(err: RecvTimeoutError) -> Self {
Self::from(err.to_string())
}
}
impl From<FromBytesError> for AppError {
fn from(err: FromBytesError) -> Self {
Self::from(err.to_string())
}
}