tokio_binance/
error.rs

1use std::fmt;
2use std::error;
3use async_tungstenite::tungstenite::protocol::frame::coding::CloseCode;
4
5pub type Result<T> = std::result::Result<T, Error>;
6pub(crate) type BoxError = Box<dyn error::Error + Send + Sync>;
7
8#[derive(Debug)]
9pub(super) enum Kind {
10    Binance,
11    SerdeUrlEncoded,
12    Reqwest,
13    Tungstenite,
14    SerdeJson,
15    Hmac,
16    Url,
17}
18
19#[derive(Debug)]
20pub struct WsCloseError {
21    code: CloseCode,
22    reason: String,
23}
24
25impl WsCloseError {
26    pub(super) fn new<T: Into<String>>(code: CloseCode, reason: T) -> Self {
27        WsCloseError { code, reason: reason.into() }
28    }
29}
30
31impl fmt::Display for WsCloseError {
32    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
33        write!(f, "{}", self.reason)
34    }
35}
36
37impl error::Error for WsCloseError {
38    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
39        None
40    }
41}
42
43pub struct ClientError {
44    code: u16,
45    reason: String,
46    message: String
47}
48
49impl ClientError {
50    pub(super) fn new<T: Into<String>>(code: u16, reason: T, message: T) -> Self {
51        ClientError { code, reason: reason.into(), message: message.into() }
52    }
53}
54
55impl fmt::Display for ClientError {
56    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
57        write!(f, "{}", self.message)
58    }
59}
60
61impl fmt::Debug for ClientError {
62    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63        let mut builder = f.debug_struct("ClientError");
64
65        builder.field("code", &self.code);
66        builder.field("reason", &self.reason);
67        builder.finish()
68    }
69}
70
71impl error::Error for ClientError {
72    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
73        None
74    }
75}
76
77pub struct Error {
78    kind: Kind,
79    source: Option<BoxError>
80}
81
82impl Error {
83    pub(super) fn new<E>(kind: Kind, source: Option<E>) -> Self 
84    where
85        E: Into<BoxError>,
86    {
87        Error {
88            kind,
89            source: source.map(Into::into)
90        }
91    }
92}
93
94impl fmt::Debug for Error {
95    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
96        let mut builder = f.debug_struct("tokio-binance::Error");
97
98        builder.field("kind", &self.kind);
99
100        if let Some(ref source) = self.source {
101            builder.field("source", source);
102        }
103
104        builder.finish()
105    }
106}
107
108impl error::Error for Error {
109    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
110        self.source.as_ref().map(|e| &**e as _)
111    }
112}
113
114impl fmt::Display for Error {
115    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
116        if let Some(ref source) = self.source {
117            write!(f, "{:?}: {}", self.kind, source)
118        } else {
119           write!(f, "No source for this error") 
120        }
121    }
122}
123
124impl From<ClientError> for Error {
125    fn from(error: ClientError) -> Self {
126        Error::new(Kind::Binance, Some(error))
127    }
128}
129
130impl From<WsCloseError> for Error {
131    fn from(error: WsCloseError) -> Self {
132        Error::new(Kind::Binance, Some(error))
133    }
134}
135
136impl From<reqwest::Error> for Error {
137    fn from(error: reqwest::Error) -> Self {
138        Error::new(Kind::Reqwest, Some(error))
139    }
140}
141
142impl From<serde_urlencoded::ser::Error> for Error {
143    fn from(error: serde_urlencoded::ser::Error) -> Self {
144        Error::new(Kind::SerdeUrlEncoded, Some(error))
145    }
146}
147
148impl From<async_tungstenite::tungstenite::Error> for Error {
149    fn from(error: async_tungstenite::tungstenite::Error) -> Self {
150        Error::new(Kind::Tungstenite, Some(error))
151    }
152}
153
154impl From<url::ParseError> for Error {
155    fn from(error: url::ParseError) -> Self {
156        Error::new(Kind::Url, Some(error))
157    }
158}
159
160impl From<serde_json::error::Error> for Error {
161    fn from(error: serde_json::error::Error) -> Self {
162        Error::new(Kind::SerdeJson, Some(error))
163    }
164}
165
166impl From<hmac::crypto_mac::InvalidKeyLength> for Error {
167    fn from(error: hmac::crypto_mac::InvalidKeyLength) -> Self {
168        Error::new(Kind::Hmac, Some(error))
169    }
170}