solana_rpc_client_api/
client_error.rs

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