use bls::PublicKey;
pub use sn_interface::messaging::data::Error as ErrorMsg;
use sn_interface::messaging::{
data::{CmdError, OperationId, QueryResponse},
Error as MessagingError, MsgId,
};
use sn_interface::types::Error as DtError;
use std::io;
use std::net::SocketAddr;
use thiserror::Error;
pub type Result<T, E = Error> = std::result::Result<T, E>;
#[allow(clippy::large_enum_variant)]
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum Error {
#[error("Initial network contact probe failed.")]
NetworkContact,
#[error("Genesis Key from the config and the PrefixMap mismatch. You may need to remove your prefixmap or update your config file.")]
GenesisKeyMismatch,
#[error("Error reading home dir for client")]
CouldNotReadHomeDir,
#[error("Error creating .safe dir for client")]
CouldNotCreateSafeDir,
#[error("Unexpected event received")]
ReceivedUnexpectedEvent,
#[error("Client has not yet acquired any network knowledge, so anything sent is guaranteed to have a lengthy AE process")]
NoNetworkKnowledge,
#[error("An error was returned from IncomingMessages on one of our connections")]
IncomingMessages,
#[error(
"Problem connecting to sufficient elders. A supermajority of responses is unobtainable. {connections} were connected to, {required} needed."
)]
InsufficientElderConnections {
connections: usize,
required: usize,
},
#[error(
"Problem finding sufficient elders. A supermajority of responses is unobtainable. {connections} were known in this section, {required} needed. Section pk: {section_pk:?}"
)]
InsufficientElderKnowledge {
connections: usize,
required: usize,
section_pk: PublicKey,
},
#[error("Error with Peer's connection: {0:?}")]
PeerConnection(SocketAddr),
#[error("Cannot store empty file.")]
EmptyFileProvided,
#[error("Not enough bytes for self-encryption. Try storing it as a SmallFile.")]
TooSmallForSelfEncryption,
#[error("You might need to pad the `SmallFile` contents and then store it as a `LargeFile`, as the encryption has made it slightly too big")]
SmallFilePaddingNeeded,
#[error(
"The provided bytes is too large to store as a `SmallFile`. Store as a LargeFile instead."
)]
TooLargeAsSmallFile,
#[error("Query timed out")]
QueryTimedOut,
#[error("Could not get an encryption object.")]
NoEncryptionObject,
#[error("Failed to obtain any response")]
NoResponse,
#[error("Could not retrieve the operation id of a query response")]
UnknownOperationId,
#[error("Unexpected response received when querying {0:?}")]
UnexpectedQueryResponse(QueryResponse),
#[error(transparent)]
NetworkDataError(#[from] DtError),
#[error(
"Error received from the network: {:?} Operationid: {:?}",
source,
op_id
)]
ErrorMsg {
source: ErrorMsg,
op_id: OperationId,
},
#[error("Error received from the network: {:?} for cmd: {:?}", source, msg_id)]
ErrorCmd {
source: ErrorMsg,
msg_id: MsgId,
},
#[error(transparent)]
MessagingProtocol(#[from] MessagingError),
#[error(transparent)]
SelfEncryption(#[from] self_encryption::Error),
#[error(transparent)]
ConfigError(#[from] serde_json::Error),
#[error(transparent)]
IoError(#[from] io::Error),
#[error(transparent)]
EndpointSetup(#[from] qp2p::ClientEndpointError),
#[error(transparent)]
QuicP2p(#[from] qp2p::RpcError),
#[error(transparent)]
QuicP2pConnection(#[from] qp2p::ConnectionError),
#[error(transparent)]
QuicP2pSend(#[from] qp2p::SendError),
#[error(transparent)]
Serialisation(#[from] Box<bincode::ErrorKind>),
#[error("Not all chunks were retrieved, expected {expected}, retrieved {retrieved}.")]
NotEnoughChunksRetrieved {
expected: usize,
retrieved: usize,
},
#[error("Not all data was chunked, expected {expected}, but we have {chunked}.)")]
NotAllDataWasChunked {
expected: usize,
chunked: usize,
},
}
impl From<(CmdError, MsgId)> for Error {
fn from((error, msg_id): (CmdError, MsgId)) -> Self {
let CmdError::Data(source) = error;
Error::ErrorCmd { source, msg_id }
}
}
impl From<(ErrorMsg, OperationId)> for Error {
fn from((source, op_id): (ErrorMsg, OperationId)) -> Self {
Self::ErrorMsg { source, op_id }
}
}
impl From<qp2p::RecvError> for Error {
fn from(error: qp2p::RecvError) -> Self {
Self::QuicP2p(error.into())
}
}