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