1#[repr(u32)]
31#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
32pub enum ErrorCode {
33 Ok = 0,
36
37 SystemError = 1,
42 SystemBusy = 2,
44 ServiceUnavailable = 3,
46 InternalError = 4,
48 Timeout = 5,
50 Maintenance = 6,
52 DatabaseError = 7,
54 CacheError = 8,
56 NetworkError = 9,
58
59 ProtocolError = 100,
62 UnsupportedProtocol = 101,
64 InvalidPacket = 102,
66 PacketTooLarge = 103,
68 EncodingError = 104,
70 DecodingError = 105,
72
73 VersionError = 200,
76 ClientVersionTooOld = 201,
78 ClientVersionTooNew = 202,
80 IncompatibleVersion = 203,
82 DeprecatedApi = 204,
84
85 AuthRequired = 10000,
91 InvalidToken = 10001,
93 TokenExpired = 10002,
95 TokenRevoked = 10003,
97 PermissionDenied = 10004,
99 SessionExpired = 10005,
101 SessionNotFound = 10006,
103 UserBanned = 10007,
105 IpNotAllowed = 10008,
107
108 InvalidParams = 10100,
111 MissingRequiredParam = 10101,
113 InvalidParamType = 10102,
115 ParamOutOfRange = 10103,
117 InvalidFormat = 10104,
119 InvalidJson = 10105,
121 PayloadTooLarge = 10106,
123
124 OperationNotAllowed = 10200,
127 ResourceNotFound = 10201,
129 ResourceAlreadyExists = 10202,
131 ResourceDeleted = 10203,
133 DuplicateOperation = 10204,
135 OperationConflict = 10205,
137
138 RateLimitExceeded = 10300,
141 DailyQuotaExceeded = 10301,
143 MonthlyQuotaExceeded = 10302,
145 ConcurrentLimitExceeded = 10303,
147
148 MessageNotFound = 20000,
154 MessageDeleted = 20001,
156 MessageRevoked = 20002,
158 MessageSendFailed = 20003,
160 MessageTooLarge = 20004,
162 MessageTypeInvalid = 20005,
164 MessageContentInvalid = 20006,
166 MessageCannotRevoke = 20007,
168 MessageAlreadyRead = 20008,
170 SendMessageTooFast = 20009,
172
173 OfflineMessageFull = 20100,
176 OfflineMessageExpired = 20101,
178
179 UserNotFound = 20200,
182 UserAlreadyExists = 20201,
184 UserDeleted = 20202,
186 UserBannedAlt = 20203,
188 UserNotActive = 20204,
190 NicknameInvalid = 20205,
192 AvatarInvalid = 20206,
194
195 GroupNotFound = 20300,
198 GroupDeleted = 20301,
200 GroupFull = 20302,
202 NotGroupMember = 20303,
204 NotGroupAdmin = 20304,
206 NotGroupOwner = 20305,
208 GroupMuted = 20306,
210 MemberMuted = 20307,
212 MemberAlreadyInGroup = 20308,
214 CannotRemoveOwner = 20309,
216 JoinApprovalRequired = 20310,
218
219 FriendNotFound = 20400,
222 AlreadyFriends = 20401,
224 BlockedByUser = 20402,
226 UserInBlacklist = 20403,
228 FriendRequestExpired = 20404,
230
231 ChannelNotFound = 20500,
234 ChannelDeleted = 20501,
236 ChannelMuted = 20502,
238
239 FileNotFound = 20600,
242 FileUploadFailed = 20601,
244 FileTooLarge = 20602,
246 FileTypeNotAllowed = 20603,
248 UploadTokenInvalid = 20604,
250 UploadTokenExpired = 20605,
252 StorageQuotaExceeded = 20606,
254
255 QRCodeNotFound = 20700,
258 QRCodeExpired = 20701,
260 QRCodeUsed = 20702,
262 QRCodeRevoked = 20703,
264 QRCodeLimitExceeded = 20704,
266
267 DeviceNotFound = 20800,
270 DeviceLimitExceeded = 20801,
272 DeviceNotVerified = 20802,
274}
275
276impl ErrorCode {
277 pub fn code(&self) -> u32 {
279 *self as u32
280 }
281
282 pub fn message(&self) -> &'static str {
284 match self {
285 Self::Ok => "Operation successful",
287
288 Self::SystemError => "System error",
290 Self::SystemBusy => "System busy, please retry later",
291 Self::ServiceUnavailable => "Service unavailable",
292 Self::InternalError => "Internal error",
293 Self::Timeout => "Operation timeout",
294 Self::Maintenance => "System maintenance",
295 Self::DatabaseError => "Database error",
296 Self::CacheError => "Cache error",
297 Self::NetworkError => "Network error",
298 Self::ProtocolError => "Protocol error",
299 Self::UnsupportedProtocol => "Unsupported protocol version",
300 Self::InvalidPacket => "Invalid packet",
301 Self::PacketTooLarge => "Packet too large",
302 Self::EncodingError => "Encoding error",
303 Self::DecodingError => "Decoding error",
304 Self::VersionError => "Version error",
305 Self::ClientVersionTooOld => "Client version too old",
306 Self::ClientVersionTooNew => "Client version too new",
307 Self::IncompatibleVersion => "Incompatible version",
308 Self::DeprecatedApi => "API deprecated",
309
310 Self::AuthRequired => "Authentication required",
312 Self::InvalidToken => "Invalid token",
313 Self::TokenExpired => "Token expired",
314 Self::TokenRevoked => "Token revoked",
315 Self::PermissionDenied => "Permission denied",
316 Self::SessionExpired => "Session expired",
317 Self::SessionNotFound => "Session not found",
318 Self::UserBanned => "User banned",
319 Self::IpNotAllowed => "IP address not allowed",
320 Self::InvalidParams => "Invalid parameters",
321 Self::MissingRequiredParam => "Missing required parameter",
322 Self::InvalidParamType => "Invalid parameter type",
323 Self::ParamOutOfRange => "Parameter out of range",
324 Self::InvalidFormat => "Invalid format",
325 Self::InvalidJson => "Invalid JSON format",
326 Self::PayloadTooLarge => "Payload too large",
327 Self::OperationNotAllowed => "Operation not allowed",
328 Self::ResourceNotFound => "Resource not found",
329 Self::ResourceAlreadyExists => "Resource already exists",
330 Self::ResourceDeleted => "Resource deleted",
331 Self::DuplicateOperation => "Duplicate operation",
332 Self::OperationConflict => "Operation conflict",
333 Self::RateLimitExceeded => "Rate limit exceeded",
334 Self::DailyQuotaExceeded => "Daily quota exceeded",
335 Self::MonthlyQuotaExceeded => "Monthly quota exceeded",
336 Self::ConcurrentLimitExceeded => "Concurrent limit exceeded",
337
338 Self::MessageNotFound => "Message not found",
340 Self::MessageDeleted => "Message deleted",
341 Self::MessageRevoked => "Message revoked",
342 Self::MessageSendFailed => "Message send failed",
343 Self::MessageTooLarge => "Message too large",
344 Self::MessageTypeInvalid => "Invalid message type",
345 Self::MessageContentInvalid => "Invalid message content",
346 Self::MessageCannotRevoke => "Message cannot be revoked (timeout)",
347 Self::MessageAlreadyRead => "Message already read",
348 Self::SendMessageTooFast => "Send message too fast",
349 Self::OfflineMessageFull => "Offline message queue full",
350 Self::OfflineMessageExpired => "Offline message expired",
351 Self::UserNotFound => "User not found",
352 Self::UserAlreadyExists => "User already exists",
353 Self::UserDeleted => "User deleted",
354 Self::UserBannedAlt => "User banned",
355 Self::UserNotActive => "User not active",
356 Self::NicknameInvalid => "Invalid nickname",
357 Self::AvatarInvalid => "Invalid avatar",
358 Self::GroupNotFound => "Group not found",
359 Self::GroupDeleted => "Group deleted",
360 Self::GroupFull => "Group full",
361 Self::NotGroupMember => "Not a group member",
362 Self::NotGroupAdmin => "Not a group admin",
363 Self::NotGroupOwner => "Not a group owner",
364 Self::GroupMuted => "Group muted",
365 Self::MemberMuted => "Member muted",
366 Self::MemberAlreadyInGroup => "Member already in group",
367 Self::CannotRemoveOwner => "Cannot remove owner",
368 Self::JoinApprovalRequired => "Join approval required",
369 Self::FriendNotFound => "Friend not found",
370 Self::AlreadyFriends => "Already friends",
371 Self::BlockedByUser => "Blocked by user",
372 Self::UserInBlacklist => "User in blacklist",
373 Self::FriendRequestExpired => "Friend request expired",
374 Self::ChannelNotFound => "Channel not found",
375 Self::ChannelDeleted => "Channel deleted",
376 Self::ChannelMuted => "Channel muted",
377 Self::FileNotFound => "File not found",
378 Self::FileUploadFailed => "File upload failed",
379 Self::FileTooLarge => "File too large",
380 Self::FileTypeNotAllowed => "File type not allowed",
381 Self::UploadTokenInvalid => "Upload token invalid",
382 Self::UploadTokenExpired => "Upload token expired",
383 Self::StorageQuotaExceeded => "Storage quota exceeded",
384 Self::QRCodeNotFound => "QR code not found",
385 Self::QRCodeExpired => "QR code expired",
386 Self::QRCodeUsed => "QR code used",
387 Self::QRCodeRevoked => "QR code revoked",
388 Self::QRCodeLimitExceeded => "QR code limit exceeded",
389 Self::DeviceNotFound => "Device not found",
390 Self::DeviceLimitExceeded => "Device limit exceeded",
391 Self::DeviceNotVerified => "Device not verified",
392 }
393 }
394
395 pub fn from_code(code: u32) -> Option<Self> {
397 match code {
398 0 => Some(Self::Ok),
400
401 1 => Some(Self::SystemError),
403 2 => Some(Self::SystemBusy),
404 3 => Some(Self::ServiceUnavailable),
405 4 => Some(Self::InternalError),
406 5 => Some(Self::Timeout),
407 6 => Some(Self::Maintenance),
408 7 => Some(Self::DatabaseError),
409 8 => Some(Self::CacheError),
410 9 => Some(Self::NetworkError),
411 100 => Some(Self::ProtocolError),
412 101 => Some(Self::UnsupportedProtocol),
413 102 => Some(Self::InvalidPacket),
414 103 => Some(Self::PacketTooLarge),
415 104 => Some(Self::EncodingError),
416 105 => Some(Self::DecodingError),
417 200 => Some(Self::VersionError),
418 201 => Some(Self::ClientVersionTooOld),
419 202 => Some(Self::ClientVersionTooNew),
420 203 => Some(Self::IncompatibleVersion),
421 204 => Some(Self::DeprecatedApi),
422
423 10000 => Some(Self::AuthRequired),
425 10001 => Some(Self::InvalidToken),
426 10002 => Some(Self::TokenExpired),
427 10003 => Some(Self::TokenRevoked),
428 10004 => Some(Self::PermissionDenied),
429 10005 => Some(Self::SessionExpired),
430 10006 => Some(Self::SessionNotFound),
431 10007 => Some(Self::UserBanned),
432 10008 => Some(Self::IpNotAllowed),
433 10100 => Some(Self::InvalidParams),
434 10101 => Some(Self::MissingRequiredParam),
435 10102 => Some(Self::InvalidParamType),
436 10103 => Some(Self::ParamOutOfRange),
437 10104 => Some(Self::InvalidFormat),
438 10105 => Some(Self::InvalidJson),
439 10106 => Some(Self::PayloadTooLarge),
440 10200 => Some(Self::OperationNotAllowed),
441 10201 => Some(Self::ResourceNotFound),
442 10202 => Some(Self::ResourceAlreadyExists),
443 10203 => Some(Self::ResourceDeleted),
444 10204 => Some(Self::DuplicateOperation),
445 10205 => Some(Self::OperationConflict),
446 10300 => Some(Self::RateLimitExceeded),
447 10301 => Some(Self::DailyQuotaExceeded),
448 10302 => Some(Self::MonthlyQuotaExceeded),
449 10303 => Some(Self::ConcurrentLimitExceeded),
450
451 20000 => Some(Self::MessageNotFound),
453 20001 => Some(Self::MessageDeleted),
454 20002 => Some(Self::MessageRevoked),
455 20003 => Some(Self::MessageSendFailed),
456 20004 => Some(Self::MessageTooLarge),
457 20005 => Some(Self::MessageTypeInvalid),
458 20006 => Some(Self::MessageContentInvalid),
459 20007 => Some(Self::MessageCannotRevoke),
460 20008 => Some(Self::MessageAlreadyRead),
461 20009 => Some(Self::SendMessageTooFast),
462 20100 => Some(Self::OfflineMessageFull),
463 20101 => Some(Self::OfflineMessageExpired),
464 20200 => Some(Self::UserNotFound),
465 20201 => Some(Self::UserAlreadyExists),
466 20202 => Some(Self::UserDeleted),
467 20203 => Some(Self::UserBannedAlt),
468 20204 => Some(Self::UserNotActive),
469 20205 => Some(Self::NicknameInvalid),
470 20206 => Some(Self::AvatarInvalid),
471 20300 => Some(Self::GroupNotFound),
472 20301 => Some(Self::GroupDeleted),
473 20302 => Some(Self::GroupFull),
474 20303 => Some(Self::NotGroupMember),
475 20304 => Some(Self::NotGroupAdmin),
476 20305 => Some(Self::NotGroupOwner),
477 20306 => Some(Self::GroupMuted),
478 20307 => Some(Self::MemberMuted),
479 20308 => Some(Self::MemberAlreadyInGroup),
480 20309 => Some(Self::CannotRemoveOwner),
481 20310 => Some(Self::JoinApprovalRequired),
482 20400 => Some(Self::FriendNotFound),
483 20401 => Some(Self::AlreadyFriends),
484 20402 => Some(Self::BlockedByUser),
485 20403 => Some(Self::UserInBlacklist),
486 20404 => Some(Self::FriendRequestExpired),
487 20500 => Some(Self::ChannelNotFound),
488 20501 => Some(Self::ChannelDeleted),
489 20502 => Some(Self::ChannelMuted),
490 20600 => Some(Self::FileNotFound),
491 20601 => Some(Self::FileUploadFailed),
492 20602 => Some(Self::FileTooLarge),
493 20603 => Some(Self::FileTypeNotAllowed),
494 20604 => Some(Self::UploadTokenInvalid),
495 20605 => Some(Self::UploadTokenExpired),
496 20606 => Some(Self::StorageQuotaExceeded),
497 20700 => Some(Self::QRCodeNotFound),
498 20701 => Some(Self::QRCodeExpired),
499 20702 => Some(Self::QRCodeUsed),
500 20703 => Some(Self::QRCodeRevoked),
501 20704 => Some(Self::QRCodeLimitExceeded),
502 20800 => Some(Self::DeviceNotFound),
503 20801 => Some(Self::DeviceLimitExceeded),
504 20802 => Some(Self::DeviceNotVerified),
505
506 _ => None,
507 }
508 }
509
510 pub fn is_system_error(&self) -> bool {
512 let code = self.code();
513 code >= 1 && code < 1000
514 }
515
516 pub fn is_common_error(&self) -> bool {
518 let code = self.code();
519 code >= 10000 && code < 20000
520 }
521
522 pub fn is_business_error(&self) -> bool {
524 let code = self.code();
525 code >= 20000
526 }
527}
528
529impl Default for ErrorCode {
530 fn default() -> Self {
531 Self::Ok
532 }
533}
534
535impl std::fmt::Display for ErrorCode {
536 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
537 write!(f, "[{}] {}", self.code(), self.message())
538 }
539}
540
541#[cfg(test)]
542mod tests {
543 use super::*;
544
545 #[test]
546 fn test_error_code_values() {
547 assert_eq!(ErrorCode::Ok.code(), 0);
548
549 assert_eq!(ErrorCode::SystemBusy.code(), 2);
551 assert_eq!(ErrorCode::ProtocolError.code(), 100);
552 assert_eq!(ErrorCode::ClientVersionTooOld.code(), 201);
553
554 assert_eq!(ErrorCode::AuthRequired.code(), 10000);
556 assert_eq!(ErrorCode::InvalidParams.code(), 10100);
557 assert_eq!(ErrorCode::RateLimitExceeded.code(), 10300);
558
559 assert_eq!(ErrorCode::MessageNotFound.code(), 20000);
561 assert_eq!(ErrorCode::OfflineMessageFull.code(), 20100);
562 assert_eq!(ErrorCode::UserNotFound.code(), 20200);
563 assert_eq!(ErrorCode::GroupNotFound.code(), 20300);
564 assert_eq!(ErrorCode::FriendNotFound.code(), 20400);
565 assert_eq!(ErrorCode::FileNotFound.code(), 20600);
566 }
567
568 #[test]
569 fn test_error_code_messages() {
570 assert_eq!(ErrorCode::Ok.message(), "Operation successful");
571 assert_eq!(
572 ErrorCode::SystemBusy.message(),
573 "System busy, please retry later"
574 );
575 assert_eq!(ErrorCode::AuthRequired.message(), "Authentication required");
576 assert_eq!(ErrorCode::MessageNotFound.message(), "Message not found");
577 }
578
579 #[test]
580 fn test_error_code_classification() {
581 assert!(ErrorCode::SystemBusy.is_system_error());
583 assert!(!ErrorCode::SystemBusy.is_common_error());
584 assert!(!ErrorCode::SystemBusy.is_business_error());
585
586 assert!(!ErrorCode::AuthRequired.is_system_error());
588 assert!(ErrorCode::AuthRequired.is_common_error());
589 assert!(!ErrorCode::AuthRequired.is_business_error());
590
591 assert!(!ErrorCode::MessageNotFound.is_system_error());
593 assert!(!ErrorCode::MessageNotFound.is_common_error());
594 assert!(ErrorCode::MessageNotFound.is_business_error());
595 }
596
597 #[test]
598 fn test_error_code_from_code() {
599 assert_eq!(ErrorCode::from_code(0), Some(ErrorCode::Ok));
600 assert_eq!(ErrorCode::from_code(2), Some(ErrorCode::SystemBusy));
601 assert_eq!(ErrorCode::from_code(10000), Some(ErrorCode::AuthRequired));
602 assert_eq!(ErrorCode::from_code(10100), Some(ErrorCode::InvalidParams));
603 assert_eq!(
604 ErrorCode::from_code(20000),
605 Some(ErrorCode::MessageNotFound)
606 );
607 assert_eq!(ErrorCode::from_code(99999), None);
608 }
609
610 #[test]
611 fn test_error_code_display() {
612 let err = ErrorCode::AuthRequired;
613 assert_eq!(err.to_string(), "[10000] Authentication required");
614
615 let err = ErrorCode::SystemBusy;
616 assert_eq!(err.to_string(), "[2] System busy, please retry later");
617
618 let err = ErrorCode::GroupNotFound;
619 assert_eq!(err.to_string(), "[20300] Group not found");
620 }
621}