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