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