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