xrpl/asynch/clients/
exceptions.rs1#[cfg(all(not(feature = "std"), feature = "websocket"))]
2use alloc::boxed::Box;
3use thiserror_no_std::Error;
4
5#[cfg(feature = "helpers")]
6use crate::asynch::wallet::exceptions::XRPLFaucetException;
7use crate::{models::XRPLModelException, XRPLSerdeJsonError};
8
9#[cfg(feature = "json-rpc")]
10use super::XRPLJsonRpcException;
11#[cfg(feature = "websocket")]
12use super::XRPLWebSocketException;
13
14pub type XRPLClientResult<T, E = XRPLClientException> = core::result::Result<T, E>;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18#[non_exhaustive]
19pub enum XRPLNetworkErrorKind {
20 ConnectionClosed,
21 AlreadyClosed,
22 ConnectionRefused,
23 ConnectionReset,
24 TimedOut,
25 Dns,
26 Tls,
27 Protocol,
28 InvalidResponse,
29 OtherIo,
30 Other,
31}
32
33#[derive(Debug, Error)]
34#[non_exhaustive]
35pub enum XRPLClientException {
36 #[error("serde_json error: {0}")]
37 XRPLSerdeJsonError(#[from] XRPLSerdeJsonError),
38 #[error("XRPL Model error: {0}")]
39 XRPLModelError(#[from] XRPLModelException),
40 #[cfg(feature = "helpers")]
41 #[error("XRPL Faucet error: {0}")]
42 XRPLFaucetError(#[from] XRPLFaucetException),
43 #[cfg(feature = "websocket")]
44 #[error("XRPL WebSocket error: {0}")]
45 XRPLWebSocketError(Box<XRPLWebSocketException>),
46 #[cfg(feature = "json-rpc")]
47 #[error("XRPL JSON-RPC error: {0}")]
48 XRPLJsonRpcError(#[from] XRPLJsonRpcException),
49 #[error("URL parse error: {0}")]
50 UrlParseError(#[from] url::ParseError),
51 #[cfg(feature = "std")]
52 #[error("I/O error: {0}")]
53 IoError(#[from] alloc::io::Error),
54}
55
56impl From<serde_json::Error> for XRPLClientException {
57 fn from(error: serde_json::Error) -> Self {
58 XRPLClientException::XRPLSerdeJsonError(XRPLSerdeJsonError::from(error))
59 }
60}
61
62#[cfg(all(not(feature = "std"), feature = "json-rpc"))]
63impl From<reqwless::Error> for XRPLClientException {
64 fn from(error: reqwless::Error) -> Self {
65 XRPLClientException::XRPLJsonRpcError(XRPLJsonRpcException::ReqwlessError(error))
66 }
67}
68
69#[cfg(feature = "websocket")]
70impl From<XRPLWebSocketException> for XRPLClientException {
71 fn from(error: XRPLWebSocketException) -> Self {
72 XRPLClientException::XRPLWebSocketError(Box::new(error))
73 }
74}
75
76#[cfg(all(feature = "std", feature = "websocket"))]
77impl From<tokio_tungstenite::tungstenite::Error> for XRPLClientException {
78 fn from(error: tokio_tungstenite::tungstenite::Error) -> Self {
79 XRPLClientException::XRPLWebSocketError(Box::new(XRPLWebSocketException::from(error)))
80 }
81}
82
83#[cfg(all(feature = "std", feature = "json-rpc"))]
84impl From<reqwest::Error> for XRPLClientException {
85 fn from(error: reqwest::Error) -> Self {
86 XRPLClientException::XRPLJsonRpcError(XRPLJsonRpcException::ReqwestError(error))
87 }
88}
89
90impl XRPLClientException {
91 pub fn network_error_kind(&self) -> Option<XRPLNetworkErrorKind> {
93 match self {
94 #[cfg(feature = "websocket")]
95 XRPLClientException::XRPLWebSocketError(error) => error.network_error_kind(),
96 #[cfg(feature = "json-rpc")]
97 XRPLClientException::XRPLJsonRpcError(error) => error.network_error_kind(),
98 #[cfg(feature = "std")]
99 XRPLClientException::IoError(error) => Some(match error.kind() {
100 alloc::io::ErrorKind::ConnectionRefused => XRPLNetworkErrorKind::ConnectionRefused,
101 alloc::io::ErrorKind::ConnectionReset => XRPLNetworkErrorKind::ConnectionReset,
102 alloc::io::ErrorKind::TimedOut => XRPLNetworkErrorKind::TimedOut,
103 _ => XRPLNetworkErrorKind::OtherIo,
104 }),
105 _ => None,
106 }
107 }
108}
109
110#[cfg(feature = "std")]
111impl alloc::error::Error for XRPLClientException {}
112
113#[cfg(all(test, feature = "std", feature = "websocket", feature = "json-rpc"))]
114mod tests {
115 use alloc::boxed::Box;
116
117 use super::*;
118 use crate::asynch::clients::{XRPLJsonRpcException, XRPLWebSocketException};
119
120 #[test]
121 fn maps_client_network_error_kinds() {
122 let cases = [
123 (
124 XRPLClientException::XRPLWebSocketError(Box::new(
125 XRPLWebSocketException::ConnectionClosed,
126 )),
127 Some(XRPLNetworkErrorKind::ConnectionClosed),
128 ),
129 (
130 XRPLClientException::XRPLJsonRpcError(XRPLJsonRpcException::RequestError(
131 "not transport".into(),
132 )),
133 None,
134 ),
135 (
136 XRPLClientException::IoError(alloc::io::Error::from(
137 alloc::io::ErrorKind::ConnectionRefused,
138 )),
139 Some(XRPLNetworkErrorKind::ConnectionRefused),
140 ),
141 (
142 XRPLClientException::IoError(alloc::io::Error::from(
143 alloc::io::ErrorKind::ConnectionReset,
144 )),
145 Some(XRPLNetworkErrorKind::ConnectionReset),
146 ),
147 (
148 XRPLClientException::IoError(alloc::io::Error::from(
149 alloc::io::ErrorKind::TimedOut,
150 )),
151 Some(XRPLNetworkErrorKind::TimedOut),
152 ),
153 (
154 XRPLClientException::IoError(alloc::io::Error::from(alloc::io::ErrorKind::Other)),
155 Some(XRPLNetworkErrorKind::OtherIo),
156 ),
157 ];
158
159 for (error, expected) in cases {
160 assert_eq!(error.network_error_kind(), expected);
161 }
162 }
163}