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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// Copyright 2021 MaidSafe.net limited.
//
// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3.
// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed
// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. Please review the Licences for the specific language governing
// permissions and limitations relating to use of the SAFE Network Software.

use qp2p::Error as QuicP2pError;
use sn_data_types::{Error as DtError, PublicKey};
pub use sn_messaging::client::Error as ErrorMessage;
use sn_messaging::client::{CmdError, Event, QueryResponse, TransferError};
pub use sn_messaging::Error as MessagingError;
pub use sn_transfers::Error as TransfersError;
use std::io;

use thiserror::Error;

/// Client Errors
#[allow(clippy::large_enum_variant)]
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum Error {
    /// Asymmetric Key Decryption Failed.
    #[error("Asymmetric key decryption failure")]
    AsymmetricDecipherFailure,
    /// Symmetric Key Decryption Failed.
    #[error("Symmetric key decryption failure")]
    SymmetricDecipherFailure,
    /// Received unexpected data.
    #[error("Unexpected data received")]
    ReceivedUnexpectedData,
    /// Received unexpected event.
    #[error("Unexpected event received")]
    ReceivedUnexpectedEvent,
    /// Could not query elder.
    #[error("Problem querying elder")]
    ElderQuery,
    /// Could not connect to elder.
    #[error("Problem connecting to elder")]
    ElderConnection,
    /// Client has not gone trhough qp2p bootstrap process yet
    #[error("Client has failed to bootstrap yet")]
    NotBootstrapped,
    /// Could not connect to sufficient elder to retrieve reliable responses.
    #[error("Problem connecting to sufficient elder")]
    InsufficientElderConnections,
    /// Could not query elder.
    #[error("Problem receiving query via qp2p")]
    ReceivingQuery,
    /// Could not send query to elder.
    #[error("Problem sending query via qp2p")]
    SendingQuery,
    /// Could not query elder.
    #[error("Problem receiving query internally in sn_client")]
    QueryReceiverError,
    /// Could not query elder.
    #[error("Failed to obtain a response")]
    NoResponse,
    /// No transfer validation listener .
    #[error("Failed to obtain a response")]
    NoTransferValidationListener,
    /// Unexpected message type receivied while joining.
    #[error("Unexpected message type receivied while joining: {0}")]
    UnexpectedMessageOnJoin(String),
    /// Permission set provided is not a PublicPermissionSet.
    #[error("Expected public permission set")]
    NotPublicPermissions,
    /// Permission set provided is not a PrivatePermissionSet.
    #[error("Expected private permission set")]
    NotPrivatePermissions,
    /// Did not receive an incoming connection listener from qp2p
    #[error("Could not listen on elder connection")]
    NoElderListenerEstablished,
    /// Incorrect user permissions were returned
    #[error(" Incorrect user permissions were returned")]
    IncorrectPermissions,
    /// Unexpcted transfer event received
    #[error("Unexpcted transfer event received {0:?}")]
    UnexpectedTransferEvent(Event),
    /// Unexpcted response received
    #[error("Unexpected response received when querying {0:?}")]
    UnexpectedQueryResponse(QueryResponse),
    /// Unexpected response received
    #[error("Unexpected response received when querying balance history {0:?}")]
    UnexpectedHistoryResponse(QueryResponse),
    /// Unexpected response received
    #[error("Unexpected response received when querying store cost: {0:?}")]
    UnexpectedStoreCostResponse(QueryResponse),
    /// Unexpected response received
    #[error("Unexpected response received when querying replica keys for PublicKey: {0:?}")]
    UnexpectedReplicaKeysResponse(PublicKey),
    /// Transfer actor failed generating a transfer
    #[error("No transfer generated by transfer actor")]
    NoTransferGenerated,
    /// Transfer actor did not find any events to register locally
    #[error("Transfer actor did not find any events to register locally")]
    NoTransferEventsForLocalActor,
    /// Not in testnet "simulated payout" mode
    #[error("Simulated payouts unavailable without 'simualted-payouts' feature flag at build")]
    NotBuiltWithSimulatedPayouts,
    /// Other sn_data_types errors
    #[error(transparent)]
    NetworkDataError(#[from] DtError),
    /// Transfers errors
    #[error(transparent)]
    Transfer(#[from] TransfersError),
    /// Errors received from the network via sn_messaging
    #[error(transparent)]
    ErrorMessage(#[from] ErrorMessage),
    /// Errors occurred when serialising or deserialising messages
    #[error(transparent)]
    MessagingProtocol(#[from] MessagingError),
    /// self_enryption errors
    #[error(transparent)]
    SelfEncryption(#[from] self_encryption::SelfEncryptionError),
    /// Other sn_data_types errors
    #[error(transparent)]
    ConfigError(#[from] serde_json::Error),
    /// Io error.
    #[error(transparent)]
    IoError(#[from] io::Error),
    /// QuicP2p error.
    #[error(transparent)]
    QuicP2p(#[from] QuicP2pError),
    /// Bincode error
    #[error(transparent)]
    Serialisation(#[from] Box<bincode::ErrorKind>),
}

impl From<CmdError> for Error {
    fn from(error: CmdError) -> Self {
        let err = match error {
            CmdError::Data(data_err) => data_err,
            CmdError::Transfer(err) => match err {
                TransferError::TransferValidation(err) => err,
                TransferError::TransferRegistration(err) => err,
            },
            CmdError::Auth(auth_error) => auth_error,
        };
        Error::ErrorMessage(err)
    }
}