binance_sdk/common/
errors.rs1use thiserror::Error;
2use tokio_tungstenite::tungstenite::error::ProtocolError;
3
4#[derive(Debug, Clone, Copy)]
6pub enum WebsocketConnectionFailureReason {
7 NetworkInterruption,
9 ConnectionReset,
11 ServerTemporaryError,
13 UnexpectedClose,
15 StreamEnded,
17 AuthenticationFailure,
19 ProtocolViolation,
21 ConfigurationError,
23 UserInitiatedClose,
25 PermanentServerError,
27 NormalClose,
29}
30
31impl WebsocketConnectionFailureReason {
32 pub fn from_tungstenite_error(error: &tokio_tungstenite::tungstenite::Error) -> Self {
34 use tokio_tungstenite::tungstenite::Error;
35 match error {
36 Error::ConnectionClosed | Error::AlreadyClosed => Self::ConnectionReset,
37 Error::Io(io_error) => {
38 use std::io::ErrorKind;
39 match io_error.kind() {
40 ErrorKind::ConnectionReset | ErrorKind::ConnectionAborted => {
41 Self::ConnectionReset
42 }
43 ErrorKind::UnexpectedEof => Self::StreamEnded,
44 ErrorKind::PermissionDenied => Self::AuthenticationFailure,
45 _ => Self::NetworkInterruption,
46 }
47 }
48 Error::Tls(_) | Error::Capacity(_) | Error::Url(_) => Self::ConfigurationError,
49 Error::Protocol(ProtocolError::ResetWithoutClosingHandshake) => Self::UnexpectedClose,
50 Error::Protocol(_) | Error::Utf8 | Error::HttpFormat(_) => Self::ProtocolViolation,
51 Error::Http(_) => Self::ServerTemporaryError,
52 _ => Self::NetworkInterruption,
53 }
54 }
55
56 #[must_use]
58 pub fn from_close_code(code: u16, user_initiated: bool) -> Self {
59 if user_initiated {
60 return Self::UserInitiatedClose;
61 }
62 match code {
63 1000 => Self::NormalClose, 1001 | 1011 | 1012 | 1013 => Self::ServerTemporaryError, 1002 | 1003 | 1007 | 1009 | 1010 => Self::ProtocolViolation, 1008 | 1014 | 4000..=4999 => Self::PermanentServerError, 1015 => Self::ConfigurationError, _ => Self::UnexpectedClose, }
70 }
71
72 #[must_use]
74 pub fn should_reconnect(&self) -> bool {
75 match self {
76 Self::NetworkInterruption
78 | Self::ConnectionReset
79 | Self::ServerTemporaryError
80 | Self::UnexpectedClose
81 | Self::StreamEnded => true,
82 Self::AuthenticationFailure
84 | Self::ProtocolViolation
85 | Self::ConfigurationError
86 | Self::UserInitiatedClose
87 | Self::PermanentServerError
88 | Self::NormalClose => false,
89 }
90 }
91}
92
93#[derive(Error, Debug)]
94pub enum ConnectorError {
95 #[error("Connector client error: {msg}")]
96 ConnectorClientError { msg: String, code: Option<i64> },
97
98 #[error("Unauthorized access. Authentication required. {msg}")]
99 UnauthorizedError { msg: String, code: Option<i64> },
100
101 #[error("Access to the requested resource is forbidden. {msg}")]
102 ForbiddenError { msg: String, code: Option<i64> },
103
104 #[error("Too many requests. You are being rate-limited. {msg}")]
105 TooManyRequestsError { msg: String, code: Option<i64> },
106
107 #[error("The IP address has been banned for exceeding rate limits. {msg}")]
108 RateLimitBanError { msg: String, code: Option<i64> },
109
110 #[error("Internal server error: {msg} (status code: {status_code:?})")]
111 ServerError {
112 msg: String,
113 status_code: Option<u16>,
114 },
115
116 #[error("Network error: {0}")]
117 NetworkError(String),
118
119 #[error("The requested resource was not found. {msg}")]
120 NotFoundError { msg: String, code: Option<i64> },
121
122 #[error("Bad request: {msg}")]
123 BadRequestError { msg: String, code: Option<i64> },
124}
125
126#[derive(Debug, Error)]
127pub enum WebsocketError {
128 #[error("WebSocket timeout error")]
129 Timeout,
130 #[error("WebSocket protocol error: {0}")]
131 Protocol(String),
132 #[error("URL parse error: {0}")]
133 Url(#[from] url::ParseError),
134 #[error("WebSocket handshake error: {0}")]
135 Handshake(String),
136 #[error("Network error: {0}")]
137 NetworkError(String),
138 #[error("No active WebSocket connection error.")]
139 NotConnected,
140 #[error("Server error: {0}")]
141 ServerError(String),
142 #[error("No response error.")]
143 NoResponse,
144 #[error("Serverāside response error (code {code}): {message}")]
145 ResponseError { code: i64, message: String },
146}