solana_rpc_client_api/
client_error.rs

1pub use reqwest;
2use {
3    crate::{request, response},
4    solana_signer::SignerError,
5    solana_transaction_error::{TransactionError, TransportError},
6    std::io,
7    thiserror::Error as ThisError,
8};
9
10#[derive(ThisError, Debug)]
11pub enum ErrorKind {
12    #[error(transparent)]
13    Io(#[from] io::Error),
14    #[error(transparent)]
15    Reqwest(#[from] reqwest::Error),
16    #[error("Middleware: {0}")]
17    Middleware(anyhow::Error),
18    #[error(transparent)]
19    RpcError(#[from] request::RpcError),
20    #[error(transparent)]
21    SerdeJson(#[from] serde_json::error::Error),
22    #[error(transparent)]
23    SigningError(#[from] SignerError),
24    #[error(transparent)]
25    TransactionError(#[from] TransactionError),
26    #[error("Custom: {0}")]
27    Custom(String),
28}
29
30impl ErrorKind {
31    pub fn get_transaction_error(&self) -> Option<TransactionError> {
32        match self {
33            Self::RpcError(request::RpcError::RpcResponseError {
34                data:
35                    request::RpcResponseErrorData::SendTransactionPreflightFailure(
36                        response::RpcSimulateTransactionResult {
37                            err: Some(tx_err), ..
38                        },
39                    ),
40                ..
41            }) => Some(tx_err.clone()),
42            Self::TransactionError(tx_err) => Some(tx_err.clone()),
43            _ => None,
44        }
45    }
46}
47
48impl From<TransportError> for ErrorKind {
49    fn from(err: TransportError) -> Self {
50        match err {
51            TransportError::IoError(err) => Self::Io(err),
52            TransportError::TransactionError(err) => Self::TransactionError(err),
53            TransportError::Custom(err) => Self::Custom(err),
54        }
55    }
56}
57
58impl From<ErrorKind> for TransportError {
59    fn from(client_error_kind: ErrorKind) -> Self {
60        match client_error_kind {
61            ErrorKind::Io(err) => Self::IoError(err),
62            ErrorKind::TransactionError(err) => Self::TransactionError(err),
63            ErrorKind::Reqwest(err) => Self::Custom(format!("{err:?}")),
64            ErrorKind::RpcError(err) => Self::Custom(format!("{err:?}")),
65            ErrorKind::SerdeJson(err) => Self::Custom(format!("{err:?}")),
66            ErrorKind::SigningError(err) => Self::Custom(format!("{err:?}")),
67            ErrorKind::Custom(err) => Self::Custom(format!("{err:?}")),
68            ErrorKind::Middleware(err) => Self::Custom(format!("{err:?}")),
69        }
70    }
71}
72
73#[derive(ThisError, Debug)]
74#[error("{kind}")]
75pub struct Error {
76    pub request: Option<request::RpcRequest>,
77
78    #[source]
79    pub kind: ErrorKind,
80}
81
82impl Error {
83    pub fn new_with_request(kind: ErrorKind, request: request::RpcRequest) -> Self {
84        Self {
85            request: Some(request),
86            kind,
87        }
88    }
89
90    pub fn into_with_request(self, request: request::RpcRequest) -> Self {
91        Self {
92            request: Some(request),
93            ..self
94        }
95    }
96
97    pub fn request(&self) -> Option<&request::RpcRequest> {
98        self.request.as_ref()
99    }
100
101    pub fn kind(&self) -> &ErrorKind {
102        &self.kind
103    }
104
105    pub fn get_transaction_error(&self) -> Option<TransactionError> {
106        self.kind.get_transaction_error()
107    }
108}
109
110impl From<ErrorKind> for Error {
111    fn from(kind: ErrorKind) -> Self {
112        Self {
113            request: None,
114            kind,
115        }
116    }
117}
118
119impl From<TransportError> for Error {
120    fn from(err: TransportError) -> Self {
121        Self {
122            request: None,
123            kind: err.into(),
124        }
125    }
126}
127
128impl From<Error> for TransportError {
129    fn from(client_error: Error) -> Self {
130        client_error.kind.into()
131    }
132}
133
134impl From<std::io::Error> for Error {
135    fn from(err: std::io::Error) -> Self {
136        Self {
137            request: None,
138            kind: err.into(),
139        }
140    }
141}
142
143impl From<reqwest::Error> for Error {
144    fn from(err: reqwest::Error) -> Self {
145        Self {
146            request: None,
147            kind: err.into(),
148        }
149    }
150}
151
152impl From<reqwest_middleware::Error> for Error {
153    fn from(err: reqwest_middleware::Error) -> Self {
154        let kind = match err {
155            reqwest_middleware::Error::Middleware(err) => ErrorKind::Middleware(err),
156            reqwest_middleware::Error::Reqwest(err) => err.into(),
157        };
158        Self {
159            request: None,
160            kind,
161        }
162    }
163}
164
165impl From<request::RpcError> for Error {
166    fn from(err: request::RpcError) -> Self {
167        Self {
168            request: None,
169            kind: err.into(),
170        }
171    }
172}
173
174impl From<serde_json::error::Error> for Error {
175    fn from(err: serde_json::error::Error) -> Self {
176        Self {
177            request: None,
178            kind: err.into(),
179        }
180    }
181}
182
183impl From<SignerError> for Error {
184    fn from(err: SignerError) -> Self {
185        Self {
186            request: None,
187            kind: err.into(),
188        }
189    }
190}
191
192impl From<TransactionError> for Error {
193    fn from(err: TransactionError) -> Self {
194        Self {
195            request: None,
196            kind: err.into(),
197        }
198    }
199}
200
201pub type Result<T> = std::result::Result<T, Error>;