1use serde::{Deserialize, Serialize};
4use std::fmt;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
19#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
20#[repr(u32)]
21pub enum ErrorCode {
22 ConnectionFailed = 1000,
26 ConnectionTimeout = 1001,
27 ConnectionClosed = 1002,
28 ConnectionRefused = 1003,
29 ConnectionLimitExceeded = 1004,
30 NotConnected = 1005,
31 ConnectionReconnecting = 1006,
32
33 AuthenticationFailed = 2000,
37 AuthenticationExpired = 2001,
38 AuthenticationInvalid = 2002,
39 AuthenticationRequired = 2003,
40 PermissionDenied = 2004,
41 TokenInvalid = 2005,
42 TokenExpired = 2006,
43
44 ProtocolError = 3000,
48 ProtocolVersionMismatch = 3001,
49 ProtocolNotSupported = 3002,
50 MessageFormatError = 3003,
51 MessageTooLarge = 3004,
52 InvalidCommand = 3005,
53
54 MessageSendFailed = 4000,
58 MessageDeliveryFailed = 4001,
59 MessageNotFound = 4002,
60 MessageExpired = 4003,
61 MessageRateLimitExceeded = 4004,
62 MessageDecodeFailed = 4005,
63
64 UserNotFound = 5000,
68 UserOffline = 5001,
69 UserBlocked = 5002,
70 UserQuotaExceeded = 5003,
71 UserSessionLimitExceeded = 5004,
72
73 InternalError = 6000,
77 ServiceUnavailable = 6001,
78 ResourceExhausted = 6002,
79 ConfigurationError = 6003,
80 DatabaseError = 6004,
81
82 NetworkError = 7000,
86 NetworkTimeout = 7001,
87 NetworkUnreachable = 7002,
88 NetworkConnectionLost = 7003,
89
90 SerializationError = 8000,
94 DeserializationError = 8001,
95 EncodingError = 8002,
96
97 GeneralError = 9000,
101 InvalidParameter = 9001,
102 OperationNotSupported = 9002,
103 OperationFailed = 9003,
104 OperationTimeout = 9004,
105 UnknownError = 9999,
106}
107
108impl fmt::Display for ErrorCode {
109 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110 write!(f, "{}", self.as_str())
111 }
112}
113
114impl ErrorCode {
115 #[inline]
117 pub fn as_u32(&self) -> u32 {
118 *self as u32
119 }
120
121 pub fn from_u32(code: u32) -> Option<Self> {
123 match code {
124 1000 => Some(ErrorCode::ConnectionFailed),
125 1001 => Some(ErrorCode::ConnectionTimeout),
126 1002 => Some(ErrorCode::ConnectionClosed),
127 1003 => Some(ErrorCode::ConnectionRefused),
128 1004 => Some(ErrorCode::ConnectionLimitExceeded),
129 1005 => Some(ErrorCode::NotConnected),
130 1006 => Some(ErrorCode::ConnectionReconnecting),
131 2000 => Some(ErrorCode::AuthenticationFailed),
132 2001 => Some(ErrorCode::AuthenticationExpired),
133 2002 => Some(ErrorCode::AuthenticationInvalid),
134 2003 => Some(ErrorCode::AuthenticationRequired),
135 2004 => Some(ErrorCode::PermissionDenied),
136 2005 => Some(ErrorCode::TokenInvalid),
137 2006 => Some(ErrorCode::TokenExpired),
138 3000 => Some(ErrorCode::ProtocolError),
139 3001 => Some(ErrorCode::ProtocolVersionMismatch),
140 3002 => Some(ErrorCode::ProtocolNotSupported),
141 3003 => Some(ErrorCode::MessageFormatError),
142 3004 => Some(ErrorCode::MessageTooLarge),
143 3005 => Some(ErrorCode::InvalidCommand),
144 4000 => Some(ErrorCode::MessageSendFailed),
145 4001 => Some(ErrorCode::MessageDeliveryFailed),
146 4002 => Some(ErrorCode::MessageNotFound),
147 4003 => Some(ErrorCode::MessageExpired),
148 4004 => Some(ErrorCode::MessageRateLimitExceeded),
149 4005 => Some(ErrorCode::MessageDecodeFailed),
150 5000 => Some(ErrorCode::UserNotFound),
151 5001 => Some(ErrorCode::UserOffline),
152 5002 => Some(ErrorCode::UserBlocked),
153 5003 => Some(ErrorCode::UserQuotaExceeded),
154 5004 => Some(ErrorCode::UserSessionLimitExceeded),
155 6000 => Some(ErrorCode::InternalError),
156 6001 => Some(ErrorCode::ServiceUnavailable),
157 6002 => Some(ErrorCode::ResourceExhausted),
158 6003 => Some(ErrorCode::ConfigurationError),
159 6004 => Some(ErrorCode::DatabaseError),
160 7000 => Some(ErrorCode::NetworkError),
161 7001 => Some(ErrorCode::NetworkTimeout),
162 7002 => Some(ErrorCode::NetworkUnreachable),
163 7003 => Some(ErrorCode::NetworkConnectionLost),
164 8000 => Some(ErrorCode::SerializationError),
165 8001 => Some(ErrorCode::DeserializationError),
166 8002 => Some(ErrorCode::EncodingError),
167 9000 => Some(ErrorCode::GeneralError),
168 9001 => Some(ErrorCode::InvalidParameter),
169 9002 => Some(ErrorCode::OperationNotSupported),
170 9003 => Some(ErrorCode::OperationFailed),
171 9004 => Some(ErrorCode::OperationTimeout),
172 9999 => Some(ErrorCode::UnknownError),
173 _ => None,
174 }
175 }
176
177 pub fn as_str(&self) -> &'static str {
179 match self {
180 ErrorCode::ConnectionFailed => "CONNECTION_FAILED",
181 ErrorCode::ConnectionTimeout => "CONNECTION_TIMEOUT",
182 ErrorCode::ConnectionClosed => "CONNECTION_CLOSED",
183 ErrorCode::ConnectionRefused => "CONNECTION_REFUSED",
184 ErrorCode::ConnectionLimitExceeded => "CONNECTION_LIMIT_EXCEEDED",
185 ErrorCode::NotConnected => "NOT_CONNECTED",
186 ErrorCode::ConnectionReconnecting => "CONNECTION_RECONNECTING",
187 ErrorCode::AuthenticationFailed => "AUTHENTICATION_FAILED",
188 ErrorCode::AuthenticationExpired => "AUTHENTICATION_EXPIRED",
189 ErrorCode::AuthenticationInvalid => "AUTHENTICATION_INVALID",
190 ErrorCode::AuthenticationRequired => "AUTHENTICATION_REQUIRED",
191 ErrorCode::PermissionDenied => "PERMISSION_DENIED",
192 ErrorCode::TokenInvalid => "TOKEN_INVALID",
193 ErrorCode::TokenExpired => "TOKEN_EXPIRED",
194 ErrorCode::ProtocolError => "PROTOCOL_ERROR",
195 ErrorCode::ProtocolVersionMismatch => "PROTOCOL_VERSION_MISMATCH",
196 ErrorCode::ProtocolNotSupported => "PROTOCOL_NOT_SUPPORTED",
197 ErrorCode::MessageFormatError => "MESSAGE_FORMAT_ERROR",
198 ErrorCode::MessageTooLarge => "MESSAGE_TOO_LARGE",
199 ErrorCode::InvalidCommand => "INVALID_COMMAND",
200 ErrorCode::MessageSendFailed => "MESSAGE_SEND_FAILED",
201 ErrorCode::MessageDeliveryFailed => "MESSAGE_DELIVERY_FAILED",
202 ErrorCode::MessageNotFound => "MESSAGE_NOT_FOUND",
203 ErrorCode::MessageExpired => "MESSAGE_EXPIRED",
204 ErrorCode::MessageRateLimitExceeded => "MESSAGE_RATE_LIMIT_EXCEEDED",
205 ErrorCode::MessageDecodeFailed => "MESSAGE_DECODE_FAILED",
206 ErrorCode::UserNotFound => "USER_NOT_FOUND",
207 ErrorCode::UserOffline => "USER_OFFLINE",
208 ErrorCode::UserBlocked => "USER_BLOCKED",
209 ErrorCode::UserQuotaExceeded => "USER_QUOTA_EXCEEDED",
210 ErrorCode::UserSessionLimitExceeded => "USER_SESSION_LIMIT_EXCEEDED",
211 ErrorCode::InternalError => "INTERNAL_ERROR",
212 ErrorCode::ServiceUnavailable => "SERVICE_UNAVAILABLE",
213 ErrorCode::ResourceExhausted => "RESOURCE_EXHAUSTED",
214 ErrorCode::ConfigurationError => "CONFIGURATION_ERROR",
215 ErrorCode::DatabaseError => "DATABASE_ERROR",
216 ErrorCode::NetworkError => "NETWORK_ERROR",
217 ErrorCode::NetworkTimeout => "NETWORK_TIMEOUT",
218 ErrorCode::NetworkUnreachable => "NETWORK_UNREACHABLE",
219 ErrorCode::NetworkConnectionLost => "NETWORK_CONNECTION_LOST",
220 ErrorCode::SerializationError => "SERIALIZATION_ERROR",
221 ErrorCode::DeserializationError => "DESERIALIZATION_ERROR",
222 ErrorCode::EncodingError => "ENCODING_ERROR",
223 ErrorCode::GeneralError => "GENERAL_ERROR",
224 ErrorCode::InvalidParameter => "INVALID_PARAMETER",
225 ErrorCode::OperationNotSupported => "OPERATION_NOT_SUPPORTED",
226 ErrorCode::OperationFailed => "OPERATION_FAILED",
227 ErrorCode::OperationTimeout => "OPERATION_TIMEOUT",
228 ErrorCode::UnknownError => "UNKNOWN_ERROR",
229 }
230 }
231
232 pub fn category(&self) -> ErrorCategory {
234 let code = self.as_u32();
235 match code {
236 1000..=1999 => ErrorCategory::Connection,
237 2000..=2999 => ErrorCategory::Authentication,
238 3000..=3999 => ErrorCategory::Protocol,
239 4000..=4999 => ErrorCategory::Message,
240 5000..=5999 => ErrorCategory::User,
241 6000..=6999 => ErrorCategory::System,
242 7000..=7999 => ErrorCategory::Network,
243 8000..=8999 => ErrorCategory::Serialization,
244 _ => ErrorCategory::General,
245 }
246 }
247
248 pub fn is_retryable(&self) -> bool {
250 matches!(
251 self,
252 ErrorCode::ConnectionTimeout
253 | ErrorCode::ConnectionClosed
254 | ErrorCode::NetworkTimeout
255 | ErrorCode::NetworkConnectionLost
256 | ErrorCode::ServiceUnavailable
257 | ErrorCode::ResourceExhausted
258 )
259 }
260}
261
262#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
264#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
265pub enum ErrorCategory {
266 Connection,
267 Authentication,
268 Protocol,
269 Message,
270 User,
271 System,
272 Network,
273 Serialization,
274 General,
275}
276
277impl fmt::Display for ErrorCategory {
278 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
279 match self {
280 ErrorCategory::Connection => write!(f, "CONNECTION"),
281 ErrorCategory::Authentication => write!(f, "AUTHENTICATION"),
282 ErrorCategory::Protocol => write!(f, "PROTOCOL"),
283 ErrorCategory::Message => write!(f, "MESSAGE"),
284 ErrorCategory::User => write!(f, "USER"),
285 ErrorCategory::System => write!(f, "SYSTEM"),
286 ErrorCategory::Network => write!(f, "NETWORK"),
287 ErrorCategory::Serialization => write!(f, "SERIALIZATION"),
288 ErrorCategory::General => write!(f, "GENERAL"),
289 }
290 }
291}