safe_nd/
errors.rs

1// Copyright 2019 MaidSafe.net limited.
2//
3// This SAFE Network Software is licensed to you under the MIT license <LICENSE-MIT
4// https://opensource.org/licenses/MIT> or the Modified BSD license <LICENSE-BSD
5// https://opensource.org/licenses/BSD-3-Clause>, at your option. This file may not be copied,
6// modified, or distributed except according to those terms. Please review the Licences for the
7// specific language governing permissions and limitations relating to use of the SAFE Network
8// Software.
9
10use serde::{Deserialize, Serialize};
11use std::{
12    collections::BTreeMap,
13    error,
14    fmt::{self, Debug, Display, Formatter},
15    result,
16};
17
18/// A specialised `Result` type.
19pub type Result<T> = result::Result<T, Error>;
20
21/// Error debug struct
22pub struct ErrorDebug<'a, T>(pub &'a Result<T>);
23
24impl<'a, T> Debug for ErrorDebug<'a, T> {
25    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
26        if let Err(error) = self.0 {
27            write!(f, "{:?}", error)
28        } else {
29            write!(f, "Success")
30        }
31    }
32}
33
34/// Main error type for the crate.
35#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
36pub enum Error {
37    /// Access is denied for a given requester
38    AccessDenied,
39    /// Login packet does not exist
40    NoSuchLoginPacket,
41    /// Attempt to store a login packet at an already occupied address
42    LoginPacketExists,
43    /// Requested data not found
44    NoSuchData,
45    /// Attempt to create a mutable data when data with such a name already exists
46    DataExists,
47    /// Requested entry not found
48    NoSuchEntry,
49    /// Exceeded a limit on a number of entries
50    TooManyEntries,
51    /// Some entry actions are not valid.
52    InvalidEntryActions(BTreeMap<Vec<u8>, EntryError>),
53    /// Key does not exist
54    NoSuchKey,
55    /// Duplicate Entries in this push
56    DuplicateEntryKeys,
57    /// The list of owner keys is invalid
58    InvalidOwners,
59    /// Invalid version for performing a given mutating operation. Contains the
60    /// current data version.
61    InvalidSuccessor(u64),
62    /// Invalid version for performing a given mutating operation. Contains the
63    /// current owners version.
64    InvalidOwnersSuccessor(u64),
65    /// Invalid mutating operation as it causality dependency is currently not satisfied
66    OpNotCausallyReady,
67    /// Invalid Operation such as a POST on ImmutableData
68    InvalidOperation,
69    /// Mismatch between key type and signature type.
70    SigningKeyTypeMismatch,
71    /// Failed signature validation.
72    InvalidSignature,
73    /// Received a request with a duplicate MessageId
74    DuplicateMessageId,
75    /// Network error occurring at Vault level which has no bearing on clients, e.g. serialisation
76    /// failure or database failure
77    NetworkOther(String),
78    /// While parsing, precision would be lost.
79    LossOfPrecision,
80    /// The coin amount would exceed
81    /// [the maximum value for `Money`](constant.MAX_MONEY_VALUE.html).
82    ExcessiveValue,
83    /// Failed to parse the string as [`Money`](struct.Money.html).
84    FailedToParse(String),
85    /// Transfer ID already exists.
86    TransferIdExists,
87    /// Insufficient money.
88    InsufficientBalance,
89    /// Inexistent balance.
90    NoSuchBalance,
91    /// Inexistent sender balance.
92    NoSuchSender,
93    /// Inexistent recipient balance.
94    NoSuchRecipient,
95    /// Coin balance already exists.
96    BalanceExists,
97    /// Expected data size exceeded.
98    ExceededSize,
99    /// Unexpected error.
100    Unexpected(String),
101}
102
103impl<T: Into<String>> From<T> for Error {
104    fn from(err: T) -> Self {
105        Error::NetworkOther(err.into())
106    }
107}
108
109impl Display for Error {
110    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
111        match *self {
112            Error::AccessDenied => write!(f, "Access denied"),
113            Error::NoSuchLoginPacket => write!(f, "Login packet does not exist"),
114            Error::LoginPacketExists => write!(f, "Login packet already exists at this location"),
115            Error::NoSuchData => write!(f, "Requested data not found"),
116            Error::DataExists => write!(f, "Data given already exists"),
117            Error::NoSuchEntry => write!(f, "Requested entry not found"),
118            Error::TooManyEntries => write!(f, "Exceeded a limit on a number of entries"),
119            Error::InvalidEntryActions(ref errors) => {
120                write!(f, "Entry actions are invalid: {:?}", errors)
121            }
122            Error::NoSuchKey => write!(f, "Key does not exists"),
123            Error::DuplicateEntryKeys => write!(f, "Duplicate keys in this push"),
124            Error::InvalidOwners => write!(f, "The list of owner keys is invalid"),
125            Error::InvalidOperation => write!(f, "Requested operation is not allowed"),
126            Error::InvalidSuccessor(_) => {
127                write!(f, "Data given is not a valid successor of stored data")
128            }
129            Error::InvalidOwnersSuccessor(_) => {
130                write!(f, "Data given is not a valid successor of stored data")
131            }
132            Error::OpNotCausallyReady => write!(
133                f,
134                "Data operation depends on a different replica's state than the current"
135            ),
136            Error::SigningKeyTypeMismatch => {
137                write!(f, "Mismatch between key type and signature type")
138            }
139            Error::InvalidSignature => write!(f, "Failed signature validation"),
140            Error::NetworkOther(ref error) => write!(f, "Error on Vault network: {}", error),
141            Error::LossOfPrecision => {
142                write!(f, "Lost precision on the amount of money during parsing")
143            }
144            Error::ExcessiveValue => write!(
145                f,
146                "Overflow on amount of money (check the MAX_MONEY_VALUE const)"
147            ),
148            Error::FailedToParse(ref error) => {
149                write!(f, "Failed to parse from a string: {}", error)
150            }
151            Error::TransferIdExists => write!(f, "Transfer with a given ID already exists"),
152            Error::InsufficientBalance => write!(f, "Not enough money to complete this operation"),
153            Error::NoSuchBalance => write!(f, "Balance does not exist"),
154            Error::NoSuchSender => write!(f, "Sender does not exist"),
155            Error::NoSuchRecipient => write!(f, "Recipient does not exist"),
156            Error::BalanceExists => write!(f, "Balance already exists"),
157            Error::DuplicateMessageId => write!(f, "MessageId already exists"),
158            Error::ExceededSize => write!(f, "Size of the structure exceeds the limit"),
159            Error::Unexpected(ref error) => write!(f, "Unexpected error: {}", error),
160        }
161    }
162}
163
164impl error::Error for Error {
165    fn description(&self) -> &str {
166        match *self {
167            Error::AccessDenied => "Access denied",
168            Error::NoSuchLoginPacket => "Login packet does not exist",
169            Error::LoginPacketExists => "Login packet already exists at this location",
170            Error::NoSuchData => "No such data",
171            Error::DataExists => "Data exists",
172            Error::NoSuchEntry => "No such entry",
173            Error::TooManyEntries => "Too many entries",
174            Error::InvalidEntryActions(_) => "Invalid entry actions",
175            Error::NoSuchKey => "No such key",
176            Error::DuplicateEntryKeys => "Duplicate keys in this push",
177            Error::InvalidOwners => "Invalid owners",
178            Error::InvalidSuccessor(_) => "Invalid data successor",
179            Error::InvalidOwnersSuccessor(_) => "Invalid owners successor",
180            Error::OpNotCausallyReady => "Operation's is currently not causally ready",
181            Error::InvalidOperation => "Invalid operation",
182            Error::SigningKeyTypeMismatch => "Key type and signature type mismatch",
183            Error::InvalidSignature => "Invalid signature",
184            Error::NetworkOther(ref error) => error,
185            Error::LossOfPrecision => "Lost precision on the amount of money during parsing",
186            Error::ExcessiveValue => {
187                "Overflow on amount of money (check the MAX_MONEY_VALUE const)"
188            }
189            Error::FailedToParse(_) => "Failed to parse entity",
190            Error::TransferIdExists => "Transfer with a given ID already exists",
191            Error::InsufficientBalance => "Not enough money to complete this operation",
192            Error::NoSuchBalance => "Balance does not exist",
193            Error::NoSuchSender => "Sender does not exist",
194            Error::NoSuchRecipient => "Recipient does not exist",
195            Error::BalanceExists => "Balance already exists",
196            Error::DuplicateMessageId => "MessageId already exists",
197            Error::ExceededSize => "Exceeded the size limit",
198            Error::Unexpected(_) => "Unexpected error",
199        }
200    }
201}
202
203/// Entry error for `Error::InvalidEntryActions`.
204#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
205pub enum EntryError {
206    /// Entry does not exists.
207    NoSuchEntry,
208    /// Entry already exists. Contains the current entry Key.
209    EntryExists(u8),
210    /// Invalid version when updating an entry. Contains the current entry Key.
211    InvalidSuccessor(u8),
212}