light_client/rpc/
errors.rs1use std::io;
2
3use light_sdk::error::LightSdkError;
4use solana_rpc_client_api::client_error::{Error as ClientError, ErrorKind};
5use solana_transaction_error::TransactionError;
6use thiserror::Error;
7
8use crate::indexer::IndexerError;
9
10#[derive(Error, Debug)]
11pub enum RpcError {
12 #[cfg(feature = "program-test")]
13 #[error("BanksError: {0}")]
14 BanksError(#[from] solana_banks_client::BanksClientError),
15
16 #[error("Rate limited")]
17 RateLimited,
18
19 #[error("State tree lookup table not found")]
20 StateTreeLookupTableNotFound,
21
22 #[error("State tree lookup table must have a multiple of 3 addresses")]
23 InvalidStateTreeLookupTable,
24
25 #[error("Nullify table not found")]
26 NullifyTableNotFound,
27
28 #[error("TransactionError: {0}")]
29 TransactionError(#[from] TransactionError),
30
31 #[error("ClientError: {0}")]
32 ClientError(ClientError),
33
34 #[error("IoError: {0}")]
35 IoError(#[from] io::Error),
36
37 #[error("Error: `{0}`")]
38 CustomError(String),
39
40 #[error("Signing error: {0}")]
41 SigningError(String),
42
43 #[error("Assert Rpc Error: {0}")]
44 AssertRpcError(String),
45
46 #[error("Warp slot not in the future")]
48 InvalidWarpSlot,
49
50 #[cfg(feature = "program-test")]
51 #[error("LiteSVM Error: {0}")]
52 LiteSvmError(String),
53
54 #[error("Account {0} does not exist")]
55 AccountDoesNotExist(String),
56
57 #[error("Invalid response data.")]
58 InvalidResponseData,
59
60 #[error("Indexer not initialized.")]
61 IndexerNotInitialized,
62
63 #[error("Indexer error: {0}")]
64 IndexerError(#[from] IndexerError),
65
66 #[error(
67 "No state trees available, use rpc.get_latest_active_state_trees() to fetch state trees"
68 )]
69 NoStateTreesAvailable,
70
71 #[error("LightSdkError error: {0}")]
72 LightSdkError(#[from] LightSdkError),
73}
74
75impl From<light_event::error::ParseIndexerEventError> for RpcError {
76 fn from(e: light_event::error::ParseIndexerEventError) -> Self {
77 RpcError::CustomError(format!("ParseIndexerEventError: {}", e))
78 }
79}
80
81impl From<ClientError> for RpcError {
82 fn from(e: ClientError) -> Self {
83 if e.kind.get_transaction_error().is_some() {
85 return RpcError::ClientError(e);
86 }
87
88 if let ErrorKind::Reqwest(ref reqwest_err) = e.kind {
90 if let Some(status) = reqwest_err.status() {
91 if status.as_u16() == 429 {
92 return RpcError::RateLimited;
93 }
94 }
95 }
96
97 RpcError::ClientError(e)
98 }
99}
100
101impl Clone for RpcError {
102 fn clone(&self) -> Self {
103 match self {
104 #[cfg(feature = "program-test")]
105 RpcError::BanksError(_) => RpcError::CustomError("BanksError".to_string()),
106 RpcError::RateLimited => RpcError::RateLimited,
107 RpcError::TransactionError(e) => RpcError::TransactionError(e.clone()),
108 RpcError::ClientError(_) => RpcError::CustomError("ClientError".to_string()),
109 RpcError::IoError(e) => RpcError::IoError(e.kind().into()),
110 RpcError::CustomError(e) => RpcError::CustomError(e.clone()),
111 RpcError::SigningError(e) => RpcError::SigningError(e.clone()),
112 RpcError::AssertRpcError(e) => RpcError::AssertRpcError(e.clone()),
113 RpcError::InvalidWarpSlot => RpcError::InvalidWarpSlot,
114 RpcError::AccountDoesNotExist(e) => RpcError::AccountDoesNotExist(e.clone()),
115 RpcError::InvalidResponseData => RpcError::InvalidResponseData,
116 RpcError::IndexerNotInitialized => RpcError::IndexerNotInitialized,
117 RpcError::IndexerError(e) => RpcError::IndexerError(e.clone()),
118 RpcError::LightSdkError(e) => RpcError::CustomError(e.to_string()),
119 RpcError::StateTreeLookupTableNotFound => RpcError::StateTreeLookupTableNotFound,
120 RpcError::InvalidStateTreeLookupTable => RpcError::InvalidStateTreeLookupTable,
121 RpcError::NullifyTableNotFound => RpcError::NullifyTableNotFound,
122 RpcError::NoStateTreesAvailable => RpcError::NoStateTreesAvailable,
123 #[cfg(feature = "program-test")]
124 RpcError::LiteSvmError(e) => RpcError::LiteSvmError(e.clone()),
125 }
126 }
127}
128
129#[cfg(feature = "program-test")]
130impl From<litesvm::error::LiteSVMError> for RpcError {
131 fn from(e: litesvm::error::LiteSVMError) -> Self {
132 RpcError::LiteSvmError(e.to_string())
133 }
134}