near_api/
errors.rs

1use near_jsonrpc_client::{
2    errors::JsonRpcError,
3    methods::{query::RpcQueryRequest, tx::RpcTransactionError, RpcMethod},
4};
5use near_jsonrpc_primitives::types::query::QueryResponseKind;
6
7#[derive(thiserror::Error, Debug)]
8pub enum QueryCreationError {
9    #[error("Staking pool factory account ID is not defined in the network config")]
10    StakingPoolFactoryNotDefined,
11}
12
13#[derive(thiserror::Error, Debug)]
14pub enum QueryError<Method: RpcMethod>
15where
16    Method::Error: std::fmt::Debug + std::fmt::Display + 'static,
17{
18    #[error(transparent)]
19    QueryCreationError(#[from] QueryCreationError),
20    #[error("Unexpected response kind: expected {expected} type, but got {got:?}")]
21    UnexpectedResponse {
22        expected: &'static str,
23        // Boxed to avoid large error type
24        got: Box<QueryResponseKind>,
25    },
26    #[error("Failed to deserialize response: {0}")]
27    DeserializeError(#[from] serde_json::Error),
28    #[error("Query error: {0}")]
29    JsonRpcError(Box<RetryError<JsonRpcError<Method::Error>>>),
30    #[error("Internal error: failed to get response. Please submit a bug ticket")]
31    InternalErrorNoResponse,
32}
33
34impl<Method: RpcMethod> From<RetryError<JsonRpcError<Method::Error>>> for QueryError<Method>
35where
36    Method::Error: std::fmt::Debug + std::fmt::Display + 'static,
37{
38    fn from(err: RetryError<JsonRpcError<Method::Error>>) -> Self {
39        Self::JsonRpcError(Box::new(err))
40    }
41}
42
43#[derive(thiserror::Error, Debug)]
44pub enum MetaSignError {
45    // near_primitives::action::delegate::IsDelegateAction is private, so we redefined it here
46    #[error("Attempted to construct NonDelegateAction from Action::Delegate")]
47    DelegateActionIsNotSupported,
48
49    #[error(transparent)]
50    SignerError(#[from] SignerError),
51}
52
53#[derive(thiserror::Error, Debug)]
54pub enum SignerError {
55    #[error("Public key is not available")]
56    PublicKeyIsNotAvailable,
57    #[error("Secret key is not available")]
58    SecretKeyIsNotAvailable,
59    #[error("Failed to fetch nonce: {0}")]
60    FetchNonceError(#[from] QueryError<RpcQueryRequest>),
61    #[error("IO error: {0}")]
62    IO(#[from] std::io::Error),
63
64    #[cfg(feature = "ledger")]
65    #[error(transparent)]
66    LedgerError(#[from] LedgerError),
67}
68
69#[derive(thiserror::Error, Debug)]
70pub enum SecretError {
71    #[error("Failed to process seed phrase: {0}")]
72    BIP39Error(#[from] bip39::Error),
73    #[error("Failed to derive key from seed phrase: Invalid Index")]
74    DeriveKeyInvalidIndex,
75}
76
77#[derive(thiserror::Error, Debug)]
78pub enum AccessKeyFileError {
79    #[error("Failed to read access key file: {0}")]
80    ReadError(#[from] std::io::Error),
81    #[error("Failed to parse access key file: {0}")]
82    ParseError(#[from] serde_json::Error),
83    #[error(transparent)]
84    SecretError(#[from] SecretError),
85    #[error("Public key is not linked to the private key")]
86    PrivatePublicKeyMismatch,
87}
88
89#[cfg(feature = "keystore")]
90#[derive(thiserror::Error, Debug)]
91pub enum KeyStoreError {
92    #[error(transparent)]
93    Keystore(#[from] keyring::Error),
94    #[error("Failed to query account keys: {0}")]
95    QueryError(#[from] QueryError<RpcQueryRequest>),
96    #[error("Failed to parse access key file: {0}")]
97    ParseError(#[from] serde_json::Error),
98    #[error(transparent)]
99    SecretError(#[from] SecretError),
100    #[error("Task execution error: {0}")]
101    TaskExecutionError(#[from] tokio::task::JoinError),
102}
103
104#[cfg(feature = "ledger")]
105#[derive(thiserror::Error, Debug)]
106pub enum LedgerError {
107    #[error(
108        "Buffer overflow on Ledger device occurred. \
109Transaction is too large for signature. \
110This is resolved in https://github.com/dj8yfo/app-near-rs . \
111The status is tracked in `About` section."
112    )]
113    BufferOverflow,
114    #[error("Ledger device error: {0:?}")]
115    LedgerError(near_ledger::NEARLedgerError),
116    #[error("IO error: {0}")]
117    IO(#[from] std::io::Error),
118    #[error("Task execution error: {0}")]
119    TaskExecutionError(#[from] tokio::task::JoinError),
120    #[error("Signature is not expected to fail on deserialization: {0}")]
121    SignatureDeserializationError(#[from] near_crypto::ParseSignatureError),
122}
123
124#[cfg(feature = "ledger")]
125impl From<near_ledger::NEARLedgerError> for LedgerError {
126    fn from(err: near_ledger::NEARLedgerError) -> Self {
127        const SW_BUFFER_OVERFLOW: &str = "0x6990";
128
129        match err {
130            near_ledger::NEARLedgerError::APDUExchangeError(msg)
131                if msg.contains(SW_BUFFER_OVERFLOW) =>
132            {
133                Self::BufferOverflow
134            }
135            near_ledger_error => Self::LedgerError(near_ledger_error),
136        }
137    }
138}
139
140#[derive(thiserror::Error, Debug)]
141pub enum SignedDelegateActionError {
142    #[error("Parsing of signed delegate action failed due to base64 sequence being invalid")]
143    Base64DecodingError,
144    #[error("Delegate action could not be deserialized from borsh: {0}")]
145    BorshError(#[from] std::io::Error),
146}
147
148#[derive(thiserror::Error, Debug)]
149pub enum SecretBuilderError<E: std::fmt::Debug> {
150    #[error("Public key is not available")]
151    PublicKeyIsNotAvailable,
152    #[error(transparent)]
153    SecretError(#[from] SecretError),
154    #[error(transparent)]
155    IO(#[from] std::io::Error),
156    #[error(transparent)]
157    CallbackError(E),
158}
159
160#[derive(thiserror::Error, Debug)]
161pub enum BuilderError {
162    #[error("Incorrect arguments: {0}")]
163    IncorrectArguments(#[from] serde_json::Error),
164}
165
166#[derive(thiserror::Error, Debug)]
167pub enum AccountCreationError {
168    #[error(transparent)]
169    BuilderError(#[from] BuilderError),
170
171    #[error("Top-level account is not allowed")]
172    TopLevelAccountIsNotAllowed,
173
174    #[error("Linkdrop is not defined in the network config")]
175    LinkdropIsNotDefined,
176
177    #[error("Account should be created as a sub-account of the signer or linkdrop account")]
178    AccountShouldBeSubAccountOfSignerOrLinkdrop,
179}
180
181#[derive(thiserror::Error, Debug)]
182pub enum FaucetError {
183    #[error("The <{0}> network config does not have a defined faucet (helper service) that can sponsor the creation of an account.")]
184    FaucetIsNotDefined(String),
185    #[error("Failed to send message: {0}")]
186    SendError(#[from] reqwest::Error),
187}
188
189#[derive(Debug, Clone, thiserror::Error, PartialEq, Eq)]
190pub enum DecimalNumberParsingError {
191    #[error("Invalid number: {0}")]
192    InvalidNumber(String),
193    #[error("Too long whole part: {0}")]
194    LongWhole(String),
195    #[error("Too long fractional part: {0}")]
196    LongFractional(String),
197}
198
199#[derive(thiserror::Error, Debug)]
200pub enum RetryError<E> {
201    #[error("No RPC endpoints are defined in the network config")]
202    NoRpcEndpoints,
203    #[error("Request failed. Retries exhausted. Last error: {0}")]
204    RetriesExhausted(E),
205    #[error("Critical error: {0}")]
206    Critical(E),
207}
208
209#[derive(thiserror::Error, Debug)]
210pub enum ExecuteTransactionError {
211    #[error("Transaction validation error: {0}")]
212    ValidationError(#[from] ValidationError),
213    #[error("Transaction signing error: {0}")]
214    SignerError(#[from] SignerError),
215    #[error("Meta-signing error: {0}")]
216    MetaSignError(#[from] MetaSignError),
217    #[error("Pre-query error: {0}")]
218    PreQueryError(#[from] QueryError<RpcQueryRequest>),
219    #[error("Transaction error: {0}")]
220    TransactionError(#[from] RetryError<JsonRpcError<RpcTransactionError>>),
221    #[deprecated(since = "0.2.1", note = "unused")]
222    #[error("Transaction error: {0}")]
223    CriticalTransactionError(JsonRpcError<RpcTransactionError>),
224    #[error(transparent)]
225    NonEmptyVecError(#[from] NonEmptyVecError),
226}
227
228#[derive(thiserror::Error, Debug)]
229pub enum ExecuteMetaTransactionsError {
230    #[error("Transaction validation error: {0}")]
231    ValidationError(#[from] ValidationError),
232    #[error("Meta-signing error: {0}")]
233    SignError(#[from] MetaSignError),
234    #[error("Pre-query error: {0}")]
235    PreQueryError(#[from] QueryError<RpcQueryRequest>),
236
237    #[error("Relayer is not defined in the network config")]
238    RelayerIsNotDefined,
239
240    #[error("Failed to send meta-transaction: {0}")]
241    SendError(#[from] reqwest::Error),
242
243    #[error(transparent)]
244    NonEmptyVecError(#[from] NonEmptyVecError),
245}
246
247#[derive(thiserror::Error, Debug)]
248pub enum FTValidatorError {
249    #[error("Metadata is not provided")]
250    NoMetadata,
251    #[error("Decimals mismatch: expected {expected}, got {got}")]
252    DecimalsMismatch { expected: u8, got: u8 },
253    #[error("Storage deposit is needed")]
254    StorageDepositNeeded,
255}
256
257#[derive(thiserror::Error, Debug)]
258pub enum FastNearError {
259    #[error("FastNear URL is not defined in the network config")]
260    FastNearUrlIsNotDefined,
261    #[error("Failed to send request: {0}")]
262    SendError(#[from] reqwest::Error),
263    #[error("Url parsing error: {0}")]
264    UrlParseError(#[from] url::ParseError),
265}
266
267//TODO: it's better to have a separate errors, but for now it would be aggregated here
268#[derive(thiserror::Error, Debug)]
269pub enum ValidationError {
270    #[error("Query error: {0}")]
271    QueryError(#[from] QueryError<RpcQueryRequest>),
272
273    #[error("Query creation error: {0}")]
274    QueryBuilderError(#[from] BuilderError),
275
276    #[error("FT Validation Error: {0}")]
277    FTValidatorError(#[from] FTValidatorError),
278
279    #[error("Account creation error: {0}")]
280    AccountCreationError(#[from] AccountCreationError),
281}
282
283#[derive(thiserror::Error, Debug)]
284pub enum MultiTransactionError {
285    #[error(transparent)]
286    NonEmptyVecError(#[from] NonEmptyVecError),
287
288    #[error(transparent)]
289    SignerError(#[from] SignerError),
290    #[error("Duplicate signer")]
291    DuplicateSigner,
292
293    #[error(transparent)]
294    SignedTransactionError(#[from] ExecuteTransactionError),
295
296    #[error("Failed to send meta-transaction: {0}")]
297    MetaTransactionError(#[from] ExecuteMetaTransactionsError),
298}
299
300#[derive(thiserror::Error, Debug)]
301pub enum NonEmptyVecError {
302    #[error("Vector is empty")]
303    EmptyVector,
304}
305
306#[derive(thiserror::Error, Debug)]
307pub enum CryptoHashError {
308    #[error(transparent)]
309    Base58DecodeError(#[from] bs58::decode::Error),
310    #[error("Incorrect hash length (expected 32, but {0} was given)")]
311    IncorrectHashLength(usize),
312}