1use std::fmt::{Display, Formatter};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5pub enum LarkErrorCode {
6 Success = 0,
8
9 AppTicketInvalid = 10012,
12 AccessTokenInvalid = 99991671,
14 AppAccessTokenInvalid = 99991664,
16 TenantAccessTokenInvalid = 99991663,
18
19 BadRequest = 400,
22 Unauthorized = 401,
24 Forbidden = 403,
26 NotFound = 404,
28 MethodNotAllowed = 405,
30 Conflict = 409,
32 TooManyRequests = 429,
34
35 InternalServerError = 500,
38 BadGateway = 502,
40 ServiceUnavailable = 503,
42 GatewayTimeout = 504,
44
45 AppNotInstalled = 10003,
48 AppStatusException = 10013,
50 AppPermissionDenied = 19001,
52 UserNotFound = 60001,
54 UserStatusException = 60002,
56 DepartmentNotFound = 60003,
58 ChatNotFound = 70001,
60 ChatTypeNotSupported = 70002,
62 MessageNotFound = 80001,
64 MessageTypeNotSupported = 80002,
66 FileNotFound = 90001,
68 FileSizeExceeded = 90002,
70 FileTypeNotSupported = 90003,
72
73 CalendarNotFound = 110001,
76 EventNotFound = 110002,
78 EventConflict = 110003,
80
81 DocumentNotFound = 120001,
84 DocumentPermissionDenied = 120002,
86 DocumentLocked = 120003,
88 SheetNotFound = 120011,
90 TableNotFound = 120021,
92
93 AppNotPublished = 130001,
96 AppVersionIncompatible = 130002,
98
99 NetworkTimeout = 999001,
102 NetworkConnectionFailed = 999002,
104 DnsResolutionFailed = 999003,
106 SslCertificateError = 999004,
108}
109
110impl LarkErrorCode {
111 pub fn from_code(code: i32) -> Option<Self> {
113 match code {
114 0 => Some(Self::Success),
115 10003 => Some(Self::AppNotInstalled),
116 10012 => Some(Self::AppTicketInvalid),
117 10013 => Some(Self::AppStatusException),
118 19001 => Some(Self::AppPermissionDenied),
119 99991671 => Some(Self::AccessTokenInvalid),
120 99991664 => Some(Self::AppAccessTokenInvalid),
121 99991663 => Some(Self::TenantAccessTokenInvalid),
122 400 => Some(Self::BadRequest),
123 401 => Some(Self::Unauthorized),
124 403 => Some(Self::Forbidden),
125 404 => Some(Self::NotFound),
126 405 => Some(Self::MethodNotAllowed),
127 409 => Some(Self::Conflict),
128 429 => Some(Self::TooManyRequests),
129 500 => Some(Self::InternalServerError),
130 502 => Some(Self::BadGateway),
131 503 => Some(Self::ServiceUnavailable),
132 504 => Some(Self::GatewayTimeout),
133 60001 => Some(Self::UserNotFound),
134 60002 => Some(Self::UserStatusException),
135 60003 => Some(Self::DepartmentNotFound),
136 70001 => Some(Self::ChatNotFound),
137 70002 => Some(Self::ChatTypeNotSupported),
138 80001 => Some(Self::MessageNotFound),
139 80002 => Some(Self::MessageTypeNotSupported),
140 90001 => Some(Self::FileNotFound),
141 90002 => Some(Self::FileSizeExceeded),
142 90003 => Some(Self::FileTypeNotSupported),
143 110001 => Some(Self::CalendarNotFound),
144 110002 => Some(Self::EventNotFound),
145 110003 => Some(Self::EventConflict),
146 120001 => Some(Self::DocumentNotFound),
147 120002 => Some(Self::DocumentPermissionDenied),
148 120003 => Some(Self::DocumentLocked),
149 120011 => Some(Self::SheetNotFound),
150 120021 => Some(Self::TableNotFound),
151 130001 => Some(Self::AppNotPublished),
152 130002 => Some(Self::AppVersionIncompatible),
153 999001 => Some(Self::NetworkTimeout),
154 999002 => Some(Self::NetworkConnectionFailed),
155 999003 => Some(Self::DnsResolutionFailed),
156 999004 => Some(Self::SslCertificateError),
157 _ => None,
158 }
159 }
160
161 pub fn description(&self) -> &'static str {
163 match self {
164 Self::Success => "操作成功",
165 Self::AppNotInstalled => "应用未安装",
166 Self::AppTicketInvalid => "应用票据无效",
167 Self::AppStatusException => "应用状态异常",
168 Self::AppPermissionDenied => "应用权限不足",
169 Self::AccessTokenInvalid => "访问令牌无效",
170 Self::AppAccessTokenInvalid => "应用访问令牌无效",
171 Self::TenantAccessTokenInvalid => "租户访问令牌无效",
172 Self::BadRequest => "请求参数错误",
173 Self::Unauthorized => "认证失败",
174 Self::Forbidden => "权限不足",
175 Self::NotFound => "资源不存在",
176 Self::MethodNotAllowed => "请求方法不允许",
177 Self::Conflict => "请求冲突",
178 Self::TooManyRequests => "请求频率过高",
179 Self::InternalServerError => "内部服务器错误",
180 Self::BadGateway => "网关错误",
181 Self::ServiceUnavailable => "服务不可用",
182 Self::GatewayTimeout => "网关超时",
183 Self::UserNotFound => "用户不存在",
184 Self::UserStatusException => "用户状态异常",
185 Self::DepartmentNotFound => "部门不存在",
186 Self::ChatNotFound => "群组不存在",
187 Self::ChatTypeNotSupported => "群组类型不支持",
188 Self::MessageNotFound => "消息不存在",
189 Self::MessageTypeNotSupported => "消息类型不支持",
190 Self::FileNotFound => "文件不存在",
191 Self::FileSizeExceeded => "文件大小超限",
192 Self::FileTypeNotSupported => "文件类型不支持",
193 Self::CalendarNotFound => "日历不存在",
194 Self::EventNotFound => "日程不存在",
195 Self::EventConflict => "日程冲突",
196 Self::DocumentNotFound => "文档不存在",
197 Self::DocumentPermissionDenied => "文档权限不足",
198 Self::DocumentLocked => "文档已锁定",
199 Self::SheetNotFound => "工作表不存在",
200 Self::TableNotFound => "表格不存在",
201 Self::AppNotPublished => "应用未发布",
202 Self::AppVersionIncompatible => "应用版本不兼容",
203 Self::NetworkTimeout => "网络连接超时",
204 Self::NetworkConnectionFailed => "网络连接失败",
205 Self::DnsResolutionFailed => "DNS解析失败",
206 Self::SslCertificateError => "SSL证书错误",
207 }
208 }
209
210 pub fn detailed_description(&self) -> &'static str {
212 match self {
213 Self::Success => "请求已成功处理",
214 Self::AppNotInstalled => "应用未安装到当前企业,请先在飞书管理后台安装应用",
215 Self::AppTicketInvalid => "应用票据已失效,SDK会自动重新申请",
216 Self::AppStatusException => "应用状态异常,请检查应用是否正常启用",
217 Self::AppPermissionDenied => "应用缺少执行此操作的权限,请在开发者后台配置相应权限",
218 Self::AccessTokenInvalid => "用户访问令牌已过期,需要重新获取用户授权",
219 Self::AppAccessTokenInvalid => "应用访问令牌无效,请检查应用ID和密钥配置",
220 Self::TenantAccessTokenInvalid => "租户访问令牌无效,请检查应用是否正确安装到企业",
221 Self::BadRequest => "请求参数格式错误或缺少必需参数",
222 Self::Unauthorized => "身份认证失败,请检查访问令牌",
223 Self::Forbidden => "当前用户或应用缺少执行此操作的权限",
224 Self::NotFound => "请求的资源不存在或已被删除",
225 Self::MethodNotAllowed => "当前API不支持此HTTP方法",
226 Self::Conflict => "请求与当前资源状态冲突",
227 Self::TooManyRequests => "请求频率超过限制,请降低请求频率",
228 Self::InternalServerError => "服务器内部错误,请稍后重试",
229 Self::BadGateway => "网关错误,请检查网络连接或稍后重试",
230 Self::ServiceUnavailable => "服务暂时不可用,请稍后重试",
231 Self::GatewayTimeout => "网关超时,请稍后重试",
232 Self::UserNotFound => "指定的用户不存在,请检查用户ID是否正确",
233 Self::UserStatusException => "用户状态异常,可能已被禁用或删除",
234 Self::DepartmentNotFound => "指定的部门不存在,请检查部门ID是否正确",
235 Self::ChatNotFound => "指定的群组不存在或机器人未加入该群组",
236 Self::ChatTypeNotSupported => "当前群组类型不支持此操作",
237 Self::MessageNotFound => "指定的消息不存在或已被删除",
238 Self::MessageTypeNotSupported => "不支持的消息类型",
239 Self::FileNotFound => "指定的文件不存在或已被删除",
240 Self::FileSizeExceeded => "文件大小超出限制,请压缩后重试",
241 Self::FileTypeNotSupported => "不支持的文件类型",
242 Self::CalendarNotFound => "指定的日历不存在",
243 Self::EventNotFound => "指定的日程不存在或已被删除",
244 Self::EventConflict => "日程时间冲突,请选择其他时间",
245 Self::DocumentNotFound => "指定的文档不存在或已被删除",
246 Self::DocumentPermissionDenied => "文档权限不足,请联系文档所有者授权",
247 Self::DocumentLocked => "文档已被其他用户锁定,请稍后再试",
248 Self::SheetNotFound => "指定的工作表不存在",
249 Self::TableNotFound => "指定的表格不存在",
250 Self::AppNotPublished => "应用尚未发布到应用商店",
251 Self::AppVersionIncompatible => "应用版本不兼容,请更新到最新版本",
252 Self::NetworkTimeout => "网络连接超时,请检查网络设置",
253 Self::NetworkConnectionFailed => "网络连接失败,请检查网络设置",
254 Self::DnsResolutionFailed => "DNS解析失败,请检查域名设置",
255 Self::SslCertificateError => "SSL证书验证失败,请检查证书配置",
256 }
257 }
258
259 pub fn is_auth_error(&self) -> bool {
261 matches!(
262 self,
263 Self::AppTicketInvalid
264 | Self::AccessTokenInvalid
265 | Self::AppAccessTokenInvalid
266 | Self::TenantAccessTokenInvalid
267 | Self::Unauthorized
268 )
269 }
270
271 pub fn is_permission_error(&self) -> bool {
273 matches!(
274 self,
275 Self::Forbidden | Self::AppPermissionDenied | Self::DocumentPermissionDenied
276 )
277 }
278
279 pub fn is_client_error(&self) -> bool {
281 let code = *self as i32;
282 (400..=499).contains(&code) && code != 429
283 }
284
285 pub fn is_server_error(&self) -> bool {
287 let code = *self as i32;
288 (500..=599).contains(&code)
289 }
290
291 pub fn is_retryable(&self) -> bool {
293 matches!(
294 self,
295 Self::TooManyRequests
296 | Self::InternalServerError
297 | Self::BadGateway
298 | Self::ServiceUnavailable
299 | Self::GatewayTimeout
300 | Self::NetworkTimeout
301 | Self::NetworkConnectionFailed
302 | Self::DnsResolutionFailed
303 )
304 }
305
306 pub fn suggested_retry_delay(&self) -> Option<u64> {
308 match self {
309 Self::TooManyRequests => Some(60), Self::InternalServerError => Some(5), Self::BadGateway => Some(3), Self::ServiceUnavailable => Some(10), Self::GatewayTimeout => Some(5), Self::NetworkTimeout => Some(3), Self::NetworkConnectionFailed => Some(5), Self::DnsResolutionFailed => Some(10), _ => None,
318 }
319 }
320
321 pub fn severity(&self) -> super::error::ErrorSeverity {
323 match self {
324 Self::Success => super::error::ErrorSeverity::Info,
325 Self::TooManyRequests => super::error::ErrorSeverity::Warning,
326 Self::BadRequest | Self::Unauthorized | Self::Forbidden | Self::NotFound => {
327 super::error::ErrorSeverity::Error
328 }
329 Self::InternalServerError | Self::ServiceUnavailable | Self::GatewayTimeout => {
330 super::error::ErrorSeverity::Critical
331 }
332 _ => super::error::ErrorSeverity::Warning,
333 }
334 }
335
336 pub fn help_url(&self) -> Option<&'static str> {
338 match self {
339 Self::AppTicketInvalid
340 | Self::AccessTokenInvalid
341 | Self::AppAccessTokenInvalid
342 | Self::TenantAccessTokenInvalid => {
343 Some("https://open.feishu.cn/document/server-docs/authentication/access-token")
344 }
345 Self::Forbidden => {
346 Some("https://open.feishu.cn/document/home/introduction-to-scope-and-authorization")
347 }
348 Self::TooManyRequests => {
349 Some("https://open.feishu.cn/document/server-docs/api-call-guide/rate-limiting")
350 }
351 _ => Some("https://open.feishu.cn/document/"),
352 }
353 }
354}
355
356impl Display for LarkErrorCode {
357 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
358 write!(f, "{} ({})", self.description(), *self as i32)
359 }
360}
361
362#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
364pub enum ErrorCategory {
365 Authentication,
367 Permission,
369 Parameter,
371 Resource,
373 Server,
375 Network,
377 RateLimit,
379 Other,
381}
382
383impl LarkErrorCode {
384 pub fn category(&self) -> ErrorCategory {
386 match self {
387 Self::AppTicketInvalid
388 | Self::AccessTokenInvalid
389 | Self::AppAccessTokenInvalid
390 | Self::TenantAccessTokenInvalid
391 | Self::Unauthorized => ErrorCategory::Authentication,
392
393 Self::Forbidden | Self::AppPermissionDenied | Self::DocumentPermissionDenied => {
394 ErrorCategory::Permission
395 }
396
397 Self::BadRequest
398 | Self::MethodNotAllowed
399 | Self::FileSizeExceeded
400 | Self::FileTypeNotSupported
401 | Self::MessageTypeNotSupported
402 | Self::ChatTypeNotSupported
403 | Self::EventConflict
404 | Self::AppVersionIncompatible => ErrorCategory::Parameter,
405
406 Self::NotFound
407 | Self::UserNotFound
408 | Self::DepartmentNotFound
409 | Self::ChatNotFound
410 | Self::MessageNotFound
411 | Self::FileNotFound
412 | Self::CalendarNotFound
413 | Self::EventNotFound
414 | Self::DocumentNotFound
415 | Self::SheetNotFound
416 | Self::TableNotFound
417 | Self::AppNotInstalled
418 | Self::AppNotPublished
419 | Self::Conflict => ErrorCategory::Resource,
420
421 Self::TooManyRequests => ErrorCategory::RateLimit,
422
423 Self::InternalServerError
424 | Self::BadGateway
425 | Self::ServiceUnavailable
426 | Self::AppStatusException
427 | Self::UserStatusException
428 | Self::DocumentLocked => ErrorCategory::Server,
429
430 Self::GatewayTimeout
431 | Self::NetworkTimeout
432 | Self::NetworkConnectionFailed
433 | Self::DnsResolutionFailed
434 | Self::SslCertificateError => ErrorCategory::Network,
435
436 Self::Success => ErrorCategory::Other,
437 }
438 }
439}
440
441#[cfg(test)]
442mod tests {
443 use super::*;
444
445 #[test]
446 fn test_error_code_from_code() {
447 assert_eq!(LarkErrorCode::from_code(0), Some(LarkErrorCode::Success));
448 assert_eq!(
449 LarkErrorCode::from_code(10012),
450 Some(LarkErrorCode::AppTicketInvalid)
451 );
452 assert_eq!(LarkErrorCode::from_code(404), Some(LarkErrorCode::NotFound));
453 assert_eq!(LarkErrorCode::from_code(999999), None);
454 }
455
456 #[test]
457 fn test_error_classification() {
458 assert!(LarkErrorCode::AccessTokenInvalid.is_auth_error());
459 assert!(LarkErrorCode::Forbidden.is_permission_error());
460 assert!(LarkErrorCode::BadRequest.is_client_error());
461 assert!(LarkErrorCode::InternalServerError.is_server_error());
462 assert!(LarkErrorCode::TooManyRequests.is_retryable());
463 }
464
465 #[test]
466 fn test_retry_delay() {
467 assert_eq!(
468 LarkErrorCode::TooManyRequests.suggested_retry_delay(),
469 Some(60)
470 );
471 assert_eq!(LarkErrorCode::Success.suggested_retry_delay(), None);
472 }
473
474 #[test]
475 fn test_error_category() {
476 assert_eq!(
478 LarkErrorCode::AccessTokenInvalid.category(),
479 ErrorCategory::Authentication
480 );
481 assert_eq!(
482 LarkErrorCode::AppTicketInvalid.category(),
483 ErrorCategory::Authentication
484 );
485 assert_eq!(
486 LarkErrorCode::Unauthorized.category(),
487 ErrorCategory::Authentication
488 );
489
490 assert_eq!(
492 LarkErrorCode::Forbidden.category(),
493 ErrorCategory::Permission
494 );
495 assert_eq!(
496 LarkErrorCode::AppPermissionDenied.category(),
497 ErrorCategory::Permission
498 );
499 assert_eq!(
500 LarkErrorCode::DocumentPermissionDenied.category(),
501 ErrorCategory::Permission
502 );
503
504 assert_eq!(
506 LarkErrorCode::BadRequest.category(),
507 ErrorCategory::Parameter
508 );
509 assert_eq!(
510 LarkErrorCode::FileSizeExceeded.category(),
511 ErrorCategory::Parameter
512 );
513 assert_eq!(
514 LarkErrorCode::EventConflict.category(),
515 ErrorCategory::Parameter
516 );
517
518 assert_eq!(LarkErrorCode::NotFound.category(), ErrorCategory::Resource);
520 assert_eq!(
521 LarkErrorCode::UserNotFound.category(),
522 ErrorCategory::Resource
523 );
524 assert_eq!(
525 LarkErrorCode::DocumentNotFound.category(),
526 ErrorCategory::Resource
527 );
528
529 assert_eq!(
531 LarkErrorCode::TooManyRequests.category(),
532 ErrorCategory::RateLimit
533 );
534
535 assert_eq!(
537 LarkErrorCode::InternalServerError.category(),
538 ErrorCategory::Server
539 );
540 assert_eq!(
541 LarkErrorCode::DocumentLocked.category(),
542 ErrorCategory::Server
543 );
544
545 assert_eq!(
547 LarkErrorCode::NetworkTimeout.category(),
548 ErrorCategory::Network
549 );
550 assert_eq!(
551 LarkErrorCode::DnsResolutionFailed.category(),
552 ErrorCategory::Network
553 );
554 }
555
556 #[test]
557 fn test_business_error_codes() {
558 assert_eq!(
560 LarkErrorCode::from_code(60001),
561 Some(LarkErrorCode::UserNotFound)
562 );
563 assert_eq!(
564 LarkErrorCode::from_code(70001),
565 Some(LarkErrorCode::ChatNotFound)
566 );
567 assert_eq!(
568 LarkErrorCode::from_code(120001),
569 Some(LarkErrorCode::DocumentNotFound)
570 );
571 assert_eq!(
572 LarkErrorCode::from_code(110001),
573 Some(LarkErrorCode::CalendarNotFound)
574 );
575
576 assert_eq!(
578 LarkErrorCode::from_code(999001),
579 Some(LarkErrorCode::NetworkTimeout)
580 );
581 assert_eq!(
582 LarkErrorCode::from_code(999004),
583 Some(LarkErrorCode::SslCertificateError)
584 );
585 }
586
587 #[test]
588 fn test_error_descriptions() {
589 assert_eq!(LarkErrorCode::Success.description(), "操作成功");
591 assert_eq!(LarkErrorCode::UserNotFound.description(), "用户不存在");
592 assert_eq!(LarkErrorCode::ChatNotFound.description(), "群组不存在");
593 assert_eq!(LarkErrorCode::DocumentLocked.description(), "文档已锁定");
594 assert_eq!(LarkErrorCode::NetworkTimeout.description(), "网络连接超时");
595
596 assert!(LarkErrorCode::UserNotFound
598 .detailed_description()
599 .contains("用户ID"));
600 assert!(LarkErrorCode::TooManyRequests
601 .detailed_description()
602 .contains("请求频率"));
603 assert!(LarkErrorCode::DocumentPermissionDenied
604 .detailed_description()
605 .contains("权限不足"));
606 }
607
608 #[test]
609 fn test_help_urls() {
610 assert!(LarkErrorCode::AccessTokenInvalid.help_url().is_some());
612 assert!(LarkErrorCode::TooManyRequests.help_url().is_some());
613 assert!(LarkErrorCode::Forbidden.help_url().is_some());
614
615 let auth_url = LarkErrorCode::AppAccessTokenInvalid.help_url().unwrap();
616 assert!(auth_url.contains("authentication"));
617
618 let rate_limit_url = LarkErrorCode::TooManyRequests.help_url().unwrap();
619 assert!(rate_limit_url.contains("rate-limiting"));
620 }
621
622 #[test]
623 fn test_severity_levels() {
624 use crate::core::error::ErrorSeverity;
625
626 assert_eq!(LarkErrorCode::Success.severity(), ErrorSeverity::Info);
628 assert_eq!(
629 LarkErrorCode::TooManyRequests.severity(),
630 ErrorSeverity::Warning
631 );
632 assert_eq!(LarkErrorCode::BadRequest.severity(), ErrorSeverity::Error);
633 assert_eq!(
634 LarkErrorCode::InternalServerError.severity(),
635 ErrorSeverity::Critical
636 );
637 }
638
639 #[test]
640 fn test_comprehensive_error_properties() {
641 let client_error = LarkErrorCode::BadRequest;
643 assert!(!client_error.is_auth_error());
644 assert!(!client_error.is_permission_error());
645 assert!(client_error.is_client_error());
646 assert!(!client_error.is_server_error());
647 assert!(!client_error.is_retryable());
648 assert_eq!(client_error.suggested_retry_delay(), None);
649 assert_eq!(client_error.category(), ErrorCategory::Parameter);
650
651 let business_error = LarkErrorCode::DocumentNotFound;
653 assert!(!business_error.is_auth_error());
654 assert!(!business_error.is_permission_error());
655 assert!(!business_error.is_client_error()); assert!(!business_error.is_server_error()); assert!(!business_error.is_retryable());
658 assert_eq!(business_error.suggested_retry_delay(), None);
659 assert_eq!(business_error.category(), ErrorCategory::Resource);
660
661 let network_error = LarkErrorCode::NetworkTimeout;
663 assert!(network_error.is_retryable());
664 assert_eq!(network_error.suggested_retry_delay(), Some(3));
665 assert_eq!(network_error.category(), ErrorCategory::Network);
666
667 let permission_error = LarkErrorCode::DocumentPermissionDenied;
669 assert!(!permission_error.is_auth_error());
670 assert!(permission_error.is_permission_error());
671 assert_eq!(permission_error.category(), ErrorCategory::Permission);
672
673 let auth_error = LarkErrorCode::AccessTokenInvalid;
675 assert!(auth_error.is_auth_error());
676 assert!(!auth_error.is_permission_error());
677 assert_eq!(auth_error.category(), ErrorCategory::Authentication);
678
679 let server_error = LarkErrorCode::InternalServerError;
681 assert!(!server_error.is_auth_error());
682 assert!(!server_error.is_permission_error());
683 assert!(!server_error.is_client_error());
684 assert!(server_error.is_server_error());
685 assert!(server_error.is_retryable());
686 assert_eq!(server_error.suggested_retry_delay(), Some(5));
687 assert_eq!(server_error.category(), ErrorCategory::Server);
688 }
689
690 #[test]
691 fn test_all_error_codes_from_code_coverage() {
692 assert_eq!(LarkErrorCode::from_code(0), Some(LarkErrorCode::Success));
694 assert_eq!(
695 LarkErrorCode::from_code(10003),
696 Some(LarkErrorCode::AppNotInstalled)
697 );
698 assert_eq!(
699 LarkErrorCode::from_code(10012),
700 Some(LarkErrorCode::AppTicketInvalid)
701 );
702 assert_eq!(
703 LarkErrorCode::from_code(10013),
704 Some(LarkErrorCode::AppStatusException)
705 );
706 assert_eq!(
707 LarkErrorCode::from_code(19001),
708 Some(LarkErrorCode::AppPermissionDenied)
709 );
710 assert_eq!(
711 LarkErrorCode::from_code(99991671),
712 Some(LarkErrorCode::AccessTokenInvalid)
713 );
714 assert_eq!(
715 LarkErrorCode::from_code(99991664),
716 Some(LarkErrorCode::AppAccessTokenInvalid)
717 );
718 assert_eq!(
719 LarkErrorCode::from_code(99991663),
720 Some(LarkErrorCode::TenantAccessTokenInvalid)
721 );
722 assert_eq!(
723 LarkErrorCode::from_code(400),
724 Some(LarkErrorCode::BadRequest)
725 );
726 assert_eq!(
727 LarkErrorCode::from_code(401),
728 Some(LarkErrorCode::Unauthorized)
729 );
730 assert_eq!(
731 LarkErrorCode::from_code(403),
732 Some(LarkErrorCode::Forbidden)
733 );
734 assert_eq!(LarkErrorCode::from_code(404), Some(LarkErrorCode::NotFound));
735 assert_eq!(
736 LarkErrorCode::from_code(405),
737 Some(LarkErrorCode::MethodNotAllowed)
738 );
739 assert_eq!(LarkErrorCode::from_code(409), Some(LarkErrorCode::Conflict));
740 assert_eq!(
741 LarkErrorCode::from_code(429),
742 Some(LarkErrorCode::TooManyRequests)
743 );
744 assert_eq!(
745 LarkErrorCode::from_code(500),
746 Some(LarkErrorCode::InternalServerError)
747 );
748 assert_eq!(
749 LarkErrorCode::from_code(502),
750 Some(LarkErrorCode::BadGateway)
751 );
752 assert_eq!(
753 LarkErrorCode::from_code(503),
754 Some(LarkErrorCode::ServiceUnavailable)
755 );
756 assert_eq!(
757 LarkErrorCode::from_code(504),
758 Some(LarkErrorCode::GatewayTimeout)
759 );
760 assert_eq!(
761 LarkErrorCode::from_code(60001),
762 Some(LarkErrorCode::UserNotFound)
763 );
764 assert_eq!(
765 LarkErrorCode::from_code(60002),
766 Some(LarkErrorCode::UserStatusException)
767 );
768 assert_eq!(
769 LarkErrorCode::from_code(60003),
770 Some(LarkErrorCode::DepartmentNotFound)
771 );
772 assert_eq!(
773 LarkErrorCode::from_code(70001),
774 Some(LarkErrorCode::ChatNotFound)
775 );
776 assert_eq!(
777 LarkErrorCode::from_code(70002),
778 Some(LarkErrorCode::ChatTypeNotSupported)
779 );
780 assert_eq!(
781 LarkErrorCode::from_code(80001),
782 Some(LarkErrorCode::MessageNotFound)
783 );
784 assert_eq!(
785 LarkErrorCode::from_code(80002),
786 Some(LarkErrorCode::MessageTypeNotSupported)
787 );
788 assert_eq!(
789 LarkErrorCode::from_code(90001),
790 Some(LarkErrorCode::FileNotFound)
791 );
792 assert_eq!(
793 LarkErrorCode::from_code(90002),
794 Some(LarkErrorCode::FileSizeExceeded)
795 );
796 assert_eq!(
797 LarkErrorCode::from_code(90003),
798 Some(LarkErrorCode::FileTypeNotSupported)
799 );
800 assert_eq!(
801 LarkErrorCode::from_code(110001),
802 Some(LarkErrorCode::CalendarNotFound)
803 );
804 assert_eq!(
805 LarkErrorCode::from_code(110002),
806 Some(LarkErrorCode::EventNotFound)
807 );
808 assert_eq!(
809 LarkErrorCode::from_code(110003),
810 Some(LarkErrorCode::EventConflict)
811 );
812 assert_eq!(
813 LarkErrorCode::from_code(120001),
814 Some(LarkErrorCode::DocumentNotFound)
815 );
816 assert_eq!(
817 LarkErrorCode::from_code(120002),
818 Some(LarkErrorCode::DocumentPermissionDenied)
819 );
820 assert_eq!(
821 LarkErrorCode::from_code(120003),
822 Some(LarkErrorCode::DocumentLocked)
823 );
824 assert_eq!(
825 LarkErrorCode::from_code(120011),
826 Some(LarkErrorCode::SheetNotFound)
827 );
828 assert_eq!(
829 LarkErrorCode::from_code(120021),
830 Some(LarkErrorCode::TableNotFound)
831 );
832 assert_eq!(
833 LarkErrorCode::from_code(130001),
834 Some(LarkErrorCode::AppNotPublished)
835 );
836 assert_eq!(
837 LarkErrorCode::from_code(130002),
838 Some(LarkErrorCode::AppVersionIncompatible)
839 );
840 assert_eq!(
841 LarkErrorCode::from_code(999001),
842 Some(LarkErrorCode::NetworkTimeout)
843 );
844 assert_eq!(
845 LarkErrorCode::from_code(999002),
846 Some(LarkErrorCode::NetworkConnectionFailed)
847 );
848 assert_eq!(
849 LarkErrorCode::from_code(999003),
850 Some(LarkErrorCode::DnsResolutionFailed)
851 );
852 assert_eq!(
853 LarkErrorCode::from_code(999004),
854 Some(LarkErrorCode::SslCertificateError)
855 );
856
857 assert_eq!(LarkErrorCode::from_code(-1), None);
859 assert_eq!(LarkErrorCode::from_code(12345), None);
860 assert_eq!(LarkErrorCode::from_code(999999), None);
861 }
862
863 #[test]
864 fn test_all_error_descriptions_coverage() {
865 assert_eq!(LarkErrorCode::Success.description(), "操作成功");
867 assert_eq!(LarkErrorCode::AppNotInstalled.description(), "应用未安装");
868 assert_eq!(
869 LarkErrorCode::AppTicketInvalid.description(),
870 "应用票据无效"
871 );
872 assert_eq!(
873 LarkErrorCode::AppStatusException.description(),
874 "应用状态异常"
875 );
876 assert_eq!(
877 LarkErrorCode::AppPermissionDenied.description(),
878 "应用权限不足"
879 );
880 assert_eq!(
881 LarkErrorCode::AccessTokenInvalid.description(),
882 "访问令牌无效"
883 );
884 assert_eq!(
885 LarkErrorCode::AppAccessTokenInvalid.description(),
886 "应用访问令牌无效"
887 );
888 assert_eq!(
889 LarkErrorCode::TenantAccessTokenInvalid.description(),
890 "租户访问令牌无效"
891 );
892 assert_eq!(LarkErrorCode::BadRequest.description(), "请求参数错误");
893 assert_eq!(LarkErrorCode::Unauthorized.description(), "认证失败");
894 assert_eq!(LarkErrorCode::Forbidden.description(), "权限不足");
895 assert_eq!(LarkErrorCode::NotFound.description(), "资源不存在");
896 assert_eq!(
897 LarkErrorCode::MethodNotAllowed.description(),
898 "请求方法不允许"
899 );
900 assert_eq!(LarkErrorCode::Conflict.description(), "请求冲突");
901 assert_eq!(LarkErrorCode::TooManyRequests.description(), "请求频率过高");
902 assert_eq!(
903 LarkErrorCode::InternalServerError.description(),
904 "内部服务器错误"
905 );
906 assert_eq!(LarkErrorCode::BadGateway.description(), "网关错误");
907 assert_eq!(
908 LarkErrorCode::ServiceUnavailable.description(),
909 "服务不可用"
910 );
911 assert_eq!(LarkErrorCode::GatewayTimeout.description(), "网关超时");
912 assert_eq!(LarkErrorCode::UserNotFound.description(), "用户不存在");
913 assert_eq!(
914 LarkErrorCode::UserStatusException.description(),
915 "用户状态异常"
916 );
917 assert_eq!(
918 LarkErrorCode::DepartmentNotFound.description(),
919 "部门不存在"
920 );
921 assert_eq!(LarkErrorCode::ChatNotFound.description(), "群组不存在");
922 assert_eq!(
923 LarkErrorCode::ChatTypeNotSupported.description(),
924 "群组类型不支持"
925 );
926 assert_eq!(LarkErrorCode::MessageNotFound.description(), "消息不存在");
927 assert_eq!(
928 LarkErrorCode::MessageTypeNotSupported.description(),
929 "消息类型不支持"
930 );
931 assert_eq!(LarkErrorCode::FileNotFound.description(), "文件不存在");
932 assert_eq!(
933 LarkErrorCode::FileSizeExceeded.description(),
934 "文件大小超限"
935 );
936 assert_eq!(
937 LarkErrorCode::FileTypeNotSupported.description(),
938 "文件类型不支持"
939 );
940 assert_eq!(LarkErrorCode::CalendarNotFound.description(), "日历不存在");
941 assert_eq!(LarkErrorCode::EventNotFound.description(), "日程不存在");
942 assert_eq!(LarkErrorCode::EventConflict.description(), "日程冲突");
943 assert_eq!(LarkErrorCode::DocumentNotFound.description(), "文档不存在");
944 assert_eq!(
945 LarkErrorCode::DocumentPermissionDenied.description(),
946 "文档权限不足"
947 );
948 assert_eq!(LarkErrorCode::DocumentLocked.description(), "文档已锁定");
949 assert_eq!(LarkErrorCode::SheetNotFound.description(), "工作表不存在");
950 assert_eq!(LarkErrorCode::TableNotFound.description(), "表格不存在");
951 assert_eq!(LarkErrorCode::AppNotPublished.description(), "应用未发布");
952 assert_eq!(
953 LarkErrorCode::AppVersionIncompatible.description(),
954 "应用版本不兼容"
955 );
956 assert_eq!(LarkErrorCode::NetworkTimeout.description(), "网络连接超时");
957 assert_eq!(
958 LarkErrorCode::NetworkConnectionFailed.description(),
959 "网络连接失败"
960 );
961 assert_eq!(
962 LarkErrorCode::DnsResolutionFailed.description(),
963 "DNS解析失败"
964 );
965 assert_eq!(
966 LarkErrorCode::SslCertificateError.description(),
967 "SSL证书错误"
968 );
969 }
970
971 #[test]
972 fn test_all_detailed_descriptions_coverage() {
973 assert!(LarkErrorCode::Success
975 .detailed_description()
976 .contains("成功处理"));
977 assert!(LarkErrorCode::AppNotInstalled
978 .detailed_description()
979 .contains("应用未安装"));
980 assert!(LarkErrorCode::AppTicketInvalid
981 .detailed_description()
982 .contains("自动重新申请"));
983 assert!(LarkErrorCode::AppPermissionDenied
984 .detailed_description()
985 .contains("开发者后台"));
986 assert!(LarkErrorCode::AccessTokenInvalid
987 .detailed_description()
988 .contains("重新获取"));
989 assert!(LarkErrorCode::BadRequest
990 .detailed_description()
991 .contains("参数格式"));
992 assert!(LarkErrorCode::TooManyRequests
993 .detailed_description()
994 .contains("降低请求频率"));
995 assert!(LarkErrorCode::UserNotFound
996 .detailed_description()
997 .contains("用户ID"));
998 assert!(LarkErrorCode::DocumentPermissionDenied
999 .detailed_description()
1000 .contains("联系文档所有者"));
1001 assert!(LarkErrorCode::NetworkTimeout
1002 .detailed_description()
1003 .contains("网络设置"));
1004 }
1005
1006 #[test]
1007 fn test_all_error_categories_coverage() {
1008 assert_eq!(
1012 LarkErrorCode::AppTicketInvalid.category(),
1013 ErrorCategory::Authentication
1014 );
1015 assert_eq!(
1016 LarkErrorCode::AccessTokenInvalid.category(),
1017 ErrorCategory::Authentication
1018 );
1019 assert_eq!(
1020 LarkErrorCode::AppAccessTokenInvalid.category(),
1021 ErrorCategory::Authentication
1022 );
1023 assert_eq!(
1024 LarkErrorCode::TenantAccessTokenInvalid.category(),
1025 ErrorCategory::Authentication
1026 );
1027 assert_eq!(
1028 LarkErrorCode::Unauthorized.category(),
1029 ErrorCategory::Authentication
1030 );
1031
1032 assert_eq!(
1034 LarkErrorCode::Forbidden.category(),
1035 ErrorCategory::Permission
1036 );
1037 assert_eq!(
1038 LarkErrorCode::AppPermissionDenied.category(),
1039 ErrorCategory::Permission
1040 );
1041 assert_eq!(
1042 LarkErrorCode::DocumentPermissionDenied.category(),
1043 ErrorCategory::Permission
1044 );
1045
1046 assert_eq!(
1048 LarkErrorCode::BadRequest.category(),
1049 ErrorCategory::Parameter
1050 );
1051 assert_eq!(
1052 LarkErrorCode::MethodNotAllowed.category(),
1053 ErrorCategory::Parameter
1054 );
1055 assert_eq!(
1056 LarkErrorCode::FileSizeExceeded.category(),
1057 ErrorCategory::Parameter
1058 );
1059 assert_eq!(
1060 LarkErrorCode::FileTypeNotSupported.category(),
1061 ErrorCategory::Parameter
1062 );
1063 assert_eq!(
1064 LarkErrorCode::MessageTypeNotSupported.category(),
1065 ErrorCategory::Parameter
1066 );
1067 assert_eq!(
1068 LarkErrorCode::ChatTypeNotSupported.category(),
1069 ErrorCategory::Parameter
1070 );
1071 assert_eq!(
1072 LarkErrorCode::EventConflict.category(),
1073 ErrorCategory::Parameter
1074 );
1075 assert_eq!(
1076 LarkErrorCode::AppVersionIncompatible.category(),
1077 ErrorCategory::Parameter
1078 );
1079
1080 assert_eq!(LarkErrorCode::NotFound.category(), ErrorCategory::Resource);
1082 assert_eq!(
1083 LarkErrorCode::UserNotFound.category(),
1084 ErrorCategory::Resource
1085 );
1086 assert_eq!(
1087 LarkErrorCode::DepartmentNotFound.category(),
1088 ErrorCategory::Resource
1089 );
1090 assert_eq!(
1091 LarkErrorCode::ChatNotFound.category(),
1092 ErrorCategory::Resource
1093 );
1094 assert_eq!(
1095 LarkErrorCode::MessageNotFound.category(),
1096 ErrorCategory::Resource
1097 );
1098 assert_eq!(
1099 LarkErrorCode::FileNotFound.category(),
1100 ErrorCategory::Resource
1101 );
1102 assert_eq!(
1103 LarkErrorCode::CalendarNotFound.category(),
1104 ErrorCategory::Resource
1105 );
1106 assert_eq!(
1107 LarkErrorCode::EventNotFound.category(),
1108 ErrorCategory::Resource
1109 );
1110 assert_eq!(
1111 LarkErrorCode::DocumentNotFound.category(),
1112 ErrorCategory::Resource
1113 );
1114 assert_eq!(
1115 LarkErrorCode::SheetNotFound.category(),
1116 ErrorCategory::Resource
1117 );
1118 assert_eq!(
1119 LarkErrorCode::TableNotFound.category(),
1120 ErrorCategory::Resource
1121 );
1122 assert_eq!(
1123 LarkErrorCode::AppNotInstalled.category(),
1124 ErrorCategory::Resource
1125 );
1126 assert_eq!(
1127 LarkErrorCode::AppNotPublished.category(),
1128 ErrorCategory::Resource
1129 );
1130 assert_eq!(LarkErrorCode::Conflict.category(), ErrorCategory::Resource);
1131
1132 assert_eq!(
1134 LarkErrorCode::TooManyRequests.category(),
1135 ErrorCategory::RateLimit
1136 );
1137
1138 assert_eq!(
1140 LarkErrorCode::InternalServerError.category(),
1141 ErrorCategory::Server
1142 );
1143 assert_eq!(LarkErrorCode::BadGateway.category(), ErrorCategory::Server);
1144 assert_eq!(
1145 LarkErrorCode::ServiceUnavailable.category(),
1146 ErrorCategory::Server
1147 );
1148 assert_eq!(
1149 LarkErrorCode::AppStatusException.category(),
1150 ErrorCategory::Server
1151 );
1152 assert_eq!(
1153 LarkErrorCode::UserStatusException.category(),
1154 ErrorCategory::Server
1155 );
1156 assert_eq!(
1157 LarkErrorCode::DocumentLocked.category(),
1158 ErrorCategory::Server
1159 );
1160
1161 assert_eq!(
1163 LarkErrorCode::GatewayTimeout.category(),
1164 ErrorCategory::Network
1165 );
1166 assert_eq!(
1167 LarkErrorCode::NetworkTimeout.category(),
1168 ErrorCategory::Network
1169 );
1170 assert_eq!(
1171 LarkErrorCode::NetworkConnectionFailed.category(),
1172 ErrorCategory::Network
1173 );
1174 assert_eq!(
1175 LarkErrorCode::DnsResolutionFailed.category(),
1176 ErrorCategory::Network
1177 );
1178 assert_eq!(
1179 LarkErrorCode::SslCertificateError.category(),
1180 ErrorCategory::Network
1181 );
1182
1183 assert_eq!(LarkErrorCode::Success.category(), ErrorCategory::Other);
1185 }
1186
1187 #[test]
1188 fn test_all_auth_errors() {
1189 assert!(LarkErrorCode::AppTicketInvalid.is_auth_error());
1191 assert!(LarkErrorCode::AccessTokenInvalid.is_auth_error());
1192 assert!(LarkErrorCode::AppAccessTokenInvalid.is_auth_error());
1193 assert!(LarkErrorCode::TenantAccessTokenInvalid.is_auth_error());
1194 assert!(LarkErrorCode::Unauthorized.is_auth_error());
1195
1196 assert!(!LarkErrorCode::Success.is_auth_error());
1198 assert!(!LarkErrorCode::Forbidden.is_auth_error());
1199 assert!(!LarkErrorCode::BadRequest.is_auth_error());
1200 assert!(!LarkErrorCode::NotFound.is_auth_error());
1201 assert!(!LarkErrorCode::InternalServerError.is_auth_error());
1202 }
1203
1204 #[test]
1205 fn test_all_permission_errors() {
1206 assert!(LarkErrorCode::Forbidden.is_permission_error());
1208 assert!(LarkErrorCode::AppPermissionDenied.is_permission_error());
1209 assert!(LarkErrorCode::DocumentPermissionDenied.is_permission_error());
1210
1211 assert!(!LarkErrorCode::Success.is_permission_error());
1213 assert!(!LarkErrorCode::Unauthorized.is_permission_error());
1214 assert!(!LarkErrorCode::BadRequest.is_permission_error());
1215 assert!(!LarkErrorCode::NotFound.is_permission_error());
1216 assert!(!LarkErrorCode::InternalServerError.is_permission_error());
1217 }
1218
1219 #[test]
1220 fn test_client_error_range() {
1221 assert!(LarkErrorCode::BadRequest.is_client_error());
1223 assert!(LarkErrorCode::Unauthorized.is_client_error());
1224 assert!(LarkErrorCode::Forbidden.is_client_error());
1225 assert!(LarkErrorCode::NotFound.is_client_error());
1226 assert!(LarkErrorCode::MethodNotAllowed.is_client_error());
1227 assert!(LarkErrorCode::Conflict.is_client_error());
1228
1229 assert!(!LarkErrorCode::TooManyRequests.is_client_error());
1231
1232 assert!(!LarkErrorCode::Success.is_client_error());
1234 assert!(!LarkErrorCode::InternalServerError.is_client_error());
1235 assert!(!LarkErrorCode::UserNotFound.is_client_error()); }
1237
1238 #[test]
1239 fn test_server_error_range() {
1240 assert!(LarkErrorCode::InternalServerError.is_server_error());
1242 assert!(LarkErrorCode::BadGateway.is_server_error());
1243 assert!(LarkErrorCode::ServiceUnavailable.is_server_error());
1244 assert!(LarkErrorCode::GatewayTimeout.is_server_error());
1245
1246 assert!(!LarkErrorCode::Success.is_server_error());
1248 assert!(!LarkErrorCode::BadRequest.is_server_error());
1249 assert!(!LarkErrorCode::UserNotFound.is_server_error()); assert!(!LarkErrorCode::NetworkTimeout.is_server_error()); }
1252
1253 #[test]
1254 fn test_all_retryable_errors() {
1255 assert!(LarkErrorCode::TooManyRequests.is_retryable());
1257 assert!(LarkErrorCode::InternalServerError.is_retryable());
1258 assert!(LarkErrorCode::BadGateway.is_retryable());
1259 assert!(LarkErrorCode::ServiceUnavailable.is_retryable());
1260 assert!(LarkErrorCode::GatewayTimeout.is_retryable());
1261 assert!(LarkErrorCode::NetworkTimeout.is_retryable());
1262 assert!(LarkErrorCode::NetworkConnectionFailed.is_retryable());
1263 assert!(LarkErrorCode::DnsResolutionFailed.is_retryable());
1264
1265 assert!(!LarkErrorCode::Success.is_retryable());
1267 assert!(!LarkErrorCode::BadRequest.is_retryable());
1268 assert!(!LarkErrorCode::Unauthorized.is_retryable());
1269 assert!(!LarkErrorCode::Forbidden.is_retryable());
1270 assert!(!LarkErrorCode::NotFound.is_retryable());
1271 assert!(!LarkErrorCode::UserNotFound.is_retryable());
1272 assert!(!LarkErrorCode::SslCertificateError.is_retryable());
1273 }
1274
1275 #[test]
1276 fn test_all_retry_delays() {
1277 assert_eq!(
1279 LarkErrorCode::TooManyRequests.suggested_retry_delay(),
1280 Some(60)
1281 );
1282 assert_eq!(
1283 LarkErrorCode::InternalServerError.suggested_retry_delay(),
1284 Some(5)
1285 );
1286 assert_eq!(LarkErrorCode::BadGateway.suggested_retry_delay(), Some(3));
1287 assert_eq!(
1288 LarkErrorCode::ServiceUnavailable.suggested_retry_delay(),
1289 Some(10)
1290 );
1291 assert_eq!(
1292 LarkErrorCode::GatewayTimeout.suggested_retry_delay(),
1293 Some(5)
1294 );
1295 assert_eq!(
1296 LarkErrorCode::NetworkTimeout.suggested_retry_delay(),
1297 Some(3)
1298 );
1299 assert_eq!(
1300 LarkErrorCode::NetworkConnectionFailed.suggested_retry_delay(),
1301 Some(5)
1302 );
1303 assert_eq!(
1304 LarkErrorCode::DnsResolutionFailed.suggested_retry_delay(),
1305 Some(10)
1306 );
1307
1308 assert_eq!(LarkErrorCode::Success.suggested_retry_delay(), None);
1310 assert_eq!(LarkErrorCode::BadRequest.suggested_retry_delay(), None);
1311 assert_eq!(LarkErrorCode::Unauthorized.suggested_retry_delay(), None);
1312 assert_eq!(
1313 LarkErrorCode::SslCertificateError.suggested_retry_delay(),
1314 None
1315 );
1316 }
1317
1318 #[test]
1319 fn test_all_help_urls() {
1320 let auth_errors = [
1322 LarkErrorCode::AppTicketInvalid,
1323 LarkErrorCode::AccessTokenInvalid,
1324 LarkErrorCode::AppAccessTokenInvalid,
1325 LarkErrorCode::TenantAccessTokenInvalid,
1326 ];
1327 for error in &auth_errors {
1328 let url = error.help_url().unwrap();
1329 assert!(url.contains("authentication"));
1330 }
1331
1332 let forbidden_url = LarkErrorCode::Forbidden.help_url().unwrap();
1333 assert!(forbidden_url.contains("scope-and-authorization"));
1334
1335 let rate_limit_url = LarkErrorCode::TooManyRequests.help_url().unwrap();
1336 assert!(rate_limit_url.contains("rate-limiting"));
1337
1338 let default_url = LarkErrorCode::UserNotFound.help_url().unwrap();
1340 assert!(default_url.contains("open.feishu.cn/document"));
1341 }
1342
1343 #[test]
1344 fn test_all_severity_levels() {
1345 use crate::core::error::ErrorSeverity;
1346
1347 assert_eq!(LarkErrorCode::Success.severity(), ErrorSeverity::Info);
1349
1350 assert_eq!(
1352 LarkErrorCode::TooManyRequests.severity(),
1353 ErrorSeverity::Warning
1354 );
1355
1356 assert_eq!(LarkErrorCode::BadRequest.severity(), ErrorSeverity::Error);
1358 assert_eq!(LarkErrorCode::Unauthorized.severity(), ErrorSeverity::Error);
1359 assert_eq!(LarkErrorCode::Forbidden.severity(), ErrorSeverity::Error);
1360 assert_eq!(LarkErrorCode::NotFound.severity(), ErrorSeverity::Error);
1361
1362 assert_eq!(
1364 LarkErrorCode::InternalServerError.severity(),
1365 ErrorSeverity::Critical
1366 );
1367 assert_eq!(
1368 LarkErrorCode::ServiceUnavailable.severity(),
1369 ErrorSeverity::Critical
1370 );
1371 assert_eq!(
1372 LarkErrorCode::GatewayTimeout.severity(),
1373 ErrorSeverity::Critical
1374 );
1375
1376 assert_eq!(
1378 LarkErrorCode::UserNotFound.severity(),
1379 ErrorSeverity::Warning
1380 );
1381 assert_eq!(
1382 LarkErrorCode::AppNotInstalled.severity(),
1383 ErrorSeverity::Warning
1384 );
1385 assert_eq!(
1386 LarkErrorCode::NetworkTimeout.severity(),
1387 ErrorSeverity::Warning
1388 );
1389 }
1390
1391 #[test]
1392 fn test_display_trait() {
1393 let error = LarkErrorCode::BadRequest;
1395 let display_str = format!("{}", error);
1396 assert!(display_str.contains("请求参数错误"));
1397 assert!(display_str.contains("400"));
1398
1399 let success = LarkErrorCode::Success;
1400 let success_str = format!("{}", success);
1401 assert!(success_str.contains("操作成功"));
1402 assert!(success_str.contains("0"));
1403 }
1404
1405 #[test]
1406 fn test_error_category_traits() {
1407 let category = ErrorCategory::Authentication;
1409
1410 let debug_str = format!("{:?}", category);
1412 assert!(debug_str.contains("Authentication"));
1413
1414 let cloned = category;
1416 assert_eq!(category, cloned);
1417
1418 assert_eq!(ErrorCategory::Authentication, ErrorCategory::Authentication);
1420 assert_ne!(ErrorCategory::Authentication, ErrorCategory::Permission);
1421
1422 use std::collections::HashMap;
1424 let mut map = HashMap::new();
1425 map.insert(category, "test");
1426 assert_eq!(map.get(&ErrorCategory::Authentication), Some(&"test"));
1427 }
1428
1429 #[test]
1430 fn test_lark_error_code_traits() {
1431 let error = LarkErrorCode::BadRequest;
1433
1434 let debug_str = format!("{:?}", error);
1436 assert!(debug_str.contains("BadRequest"));
1437
1438 let cloned = error;
1440 assert_eq!(error, cloned);
1441
1442 assert_eq!(LarkErrorCode::BadRequest, LarkErrorCode::BadRequest);
1444 assert_ne!(LarkErrorCode::BadRequest, LarkErrorCode::NotFound);
1445
1446 use std::collections::HashMap;
1448 let mut map = HashMap::new();
1449 map.insert(error, "test");
1450 assert_eq!(map.get(&LarkErrorCode::BadRequest), Some(&"test"));
1451 }
1452
1453 #[test]
1454 fn test_edge_cases() {
1455 assert_eq!(LarkErrorCode::from_code(0), Some(LarkErrorCode::Success));
1459 assert_eq!(
1460 LarkErrorCode::from_code(99991671),
1461 Some(LarkErrorCode::AccessTokenInvalid)
1462 );
1463
1464 assert_eq!(LarkErrorCode::from_code(-1), None);
1466 assert_eq!(LarkErrorCode::from_code(i32::MIN), None);
1467 assert_eq!(LarkErrorCode::from_code(i32::MAX), None);
1468
1469 let boundary_codes = [399, 400, 429, 430, 499, 500, 599, 600];
1471 for &code in &boundary_codes {
1472 match code {
1473 400 | 401 | 403 | 404 | 405 | 409 => {
1474 assert!(LarkErrorCode::from_code(code).is_some());
1475 }
1476 429 => {
1477 assert_eq!(
1478 LarkErrorCode::from_code(code),
1479 Some(LarkErrorCode::TooManyRequests)
1480 );
1481 }
1482 500 | 502 | 503 | 504 => {
1483 assert!(LarkErrorCode::from_code(code).is_some());
1484 }
1485 _ => {
1486 assert_eq!(LarkErrorCode::from_code(code), None);
1487 }
1488 }
1489 }
1490 }
1491}