near_api/
errors.rs

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