open_lark/core/
error_codes.rs

1use std::fmt::{Display, Formatter};
2
3/// 飞书API错误码的语义化枚举
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5pub enum LarkErrorCode {
6    /// 成功
7    Success = 0,
8
9    // 认证相关错误
10    /// 应用票据无效
11    AppTicketInvalid = 10012,
12    /// 访问令牌无效
13    AccessTokenInvalid = 99991671,
14    /// 应用访问令牌无效
15    AppAccessTokenInvalid = 99991664,
16    /// 租户访问令牌无效
17    TenantAccessTokenInvalid = 99991663,
18
19    // HTTP标准错误码
20    /// 请求参数错误
21    BadRequest = 400,
22    /// 认证失败
23    Unauthorized = 401,
24    /// 权限不足
25    Forbidden = 403,
26    /// 资源不存在
27    NotFound = 404,
28    /// 方法不允许
29    MethodNotAllowed = 405,
30    /// 请求冲突
31    Conflict = 409,
32    /// 请求频率过高
33    TooManyRequests = 429,
34
35    // 服务器错误
36    /// 内部服务器错误
37    InternalServerError = 500,
38    /// 网关错误
39    BadGateway = 502,
40    /// 服务不可用
41    ServiceUnavailable = 503,
42    /// 网关超时
43    GatewayTimeout = 504,
44
45    // 飞书业务错误码
46    /// 应用未安装
47    AppNotInstalled = 10003,
48    /// 应用状态异常
49    AppStatusException = 10013,
50    /// 应用权限不足
51    AppPermissionDenied = 19001,
52    /// 用户不存在
53    UserNotFound = 60001,
54    /// 用户状态异常
55    UserStatusException = 60002,
56    /// 部门不存在
57    DepartmentNotFound = 60003,
58    /// 群组不存在
59    ChatNotFound = 70001,
60    /// 群组类型不支持
61    ChatTypeNotSupported = 70002,
62    /// 消息不存在
63    MessageNotFound = 80001,
64    /// 消息类型不支持
65    MessageTypeNotSupported = 80002,
66    /// 文件不存在
67    FileNotFound = 90001,
68    /// 文件大小超限
69    FileSizeExceeded = 90002,
70    /// 文件类型不支持
71    FileTypeNotSupported = 90003,
72
73    // 日历相关错误
74    /// 日历不存在
75    CalendarNotFound = 110001,
76    /// 日程不存在
77    EventNotFound = 110002,
78    /// 日程冲突
79    EventConflict = 110003,
80
81    // 云文档相关错误
82    /// 文档不存在
83    DocumentNotFound = 120001,
84    /// 文档权限不足
85    DocumentPermissionDenied = 120002,
86    /// 文档已锁定
87    DocumentLocked = 120003,
88    /// 工作表不存在
89    SheetNotFound = 120011,
90    /// 表格不存在
91    TableNotFound = 120021,
92
93    // 应用商店相关错误
94    /// 应用未发布
95    AppNotPublished = 130001,
96    /// 应用版本不兼容
97    AppVersionIncompatible = 130002,
98
99    // 网络和传输错误
100    /// 网络连接超时
101    NetworkTimeout = 999001,
102    /// 网络连接失败
103    NetworkConnectionFailed = 999002,
104    /// DNS解析失败
105    DnsResolutionFailed = 999003,
106    /// SSL证书错误
107    SslCertificateError = 999004,
108}
109
110impl LarkErrorCode {
111    /// 从错误码数值创建枚举
112    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    /// 获取错误码的中文描述
162    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    /// 获取详细的错误说明
211    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    /// 检查是否为认证相关错误
260    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    /// 检查是否为权限相关错误
272    pub fn is_permission_error(&self) -> bool {
273        matches!(
274            self,
275            Self::Forbidden | Self::AppPermissionDenied | Self::DocumentPermissionDenied
276        )
277    }
278
279    /// 检查是否为客户端错误
280    pub fn is_client_error(&self) -> bool {
281        let code = *self as i32;
282        (400..=499).contains(&code) && code != 429
283    }
284
285    /// 检查是否为服务器错误
286    pub fn is_server_error(&self) -> bool {
287        let code = *self as i32;
288        (500..=599).contains(&code)
289    }
290
291    /// 检查是否可以重试
292    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    /// 获取建议的重试延迟时间(秒)
307    pub fn suggested_retry_delay(&self) -> Option<u64> {
308        match self {
309            Self::TooManyRequests => Some(60),        // 限流错误建议等待60秒
310            Self::InternalServerError => Some(5),     // 服务器错误建议等待5秒
311            Self::BadGateway => Some(3),              // 网关错误建议等待3秒
312            Self::ServiceUnavailable => Some(10),     // 服务不可用建议等待10秒
313            Self::GatewayTimeout => Some(5),          // 网关超时建议等待5秒
314            Self::NetworkTimeout => Some(3),          // 网络超时建议等待3秒
315            Self::NetworkConnectionFailed => Some(5), // 网络连接失败建议等待5秒
316            Self::DnsResolutionFailed => Some(10),    // DNS解析失败建议等待10秒
317            _ => None,
318        }
319    }
320
321    /// 获取错误的严重程度
322    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    /// 获取相关的帮助文档链接
337    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/// 错误码分类
363#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
364pub enum ErrorCategory {
365    /// 认证错误
366    Authentication,
367    /// 权限错误
368    Permission,
369    /// 参数错误
370    Parameter,
371    /// 资源错误
372    Resource,
373    /// 服务器错误
374    Server,
375    /// 网络错误
376    Network,
377    /// 限流错误
378    RateLimit,
379    /// 其他错误
380    Other,
381}
382
383impl LarkErrorCode {
384    /// 获取错误分类
385    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        // 认证错误
477        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        // 权限错误
491        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        // 参数错误
505        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        // 资源错误
519        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        // 限流错误
530        assert_eq!(
531            LarkErrorCode::TooManyRequests.category(),
532            ErrorCategory::RateLimit
533        );
534
535        // 服务器错误
536        assert_eq!(
537            LarkErrorCode::InternalServerError.category(),
538            ErrorCategory::Server
539        );
540        assert_eq!(
541            LarkErrorCode::DocumentLocked.category(),
542            ErrorCategory::Server
543        );
544
545        // 网络错误
546        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        // 测试业务特定错误码
559        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        // 测试网络错误码
577        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        // 测试中文描述
590        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        // 测试详细描述
597        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        // 测试帮助链接
611        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        // 测试不同严重级别
627        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        // 测试标准HTTP客户端错误
642        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        // 测试业务错误(不在HTTP范围内)
652        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()); // 120001 不在400-499范围
656        assert!(!business_error.is_server_error()); // 120001 不在500-599范围
657        assert!(!business_error.is_retryable());
658        assert_eq!(business_error.suggested_retry_delay(), None);
659        assert_eq!(business_error.category(), ErrorCategory::Resource);
660
661        // 测试网络错误的重试特性
662        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        // 测试权限错误
668        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        // 测试认证错误
674        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        // 测试服务器错误
680        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        // 测试所有错误码的from_code方法,确保完整覆盖
693        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        // 测试未知错误码
858        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        // 测试所有错误的中文描述
866        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        // 测试所有错误的详细描述(测试关键内容)
974        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        // 测试所有错误分类,确保每个枚举值都被测试
1009
1010        // Authentication 类别
1011        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        // Permission 类别
1033        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        // Parameter 类别
1047        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        // Resource 类别
1081        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        // RateLimit 类别
1133        assert_eq!(
1134            LarkErrorCode::TooManyRequests.category(),
1135            ErrorCategory::RateLimit
1136        );
1137
1138        // Server 类别
1139        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        // Network 类别
1162        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        // Other 类别
1184        assert_eq!(LarkErrorCode::Success.category(), ErrorCategory::Other);
1185    }
1186
1187    #[test]
1188    fn test_all_auth_errors() {
1189        // 测试所有认证相关错误
1190        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        // 确保非认证错误不被误判
1197        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        // 测试所有权限相关错误
1207        assert!(LarkErrorCode::Forbidden.is_permission_error());
1208        assert!(LarkErrorCode::AppPermissionDenied.is_permission_error());
1209        assert!(LarkErrorCode::DocumentPermissionDenied.is_permission_error());
1210
1211        // 确保非权限错误不被误判
1212        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        // 测试所有HTTP客户端错误(400-499,除了429)
1222        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        // 429 被排除在客户端错误之外
1230        assert!(!LarkErrorCode::TooManyRequests.is_client_error());
1231
1232        // 确保非客户端错误不被误判
1233        assert!(!LarkErrorCode::Success.is_client_error());
1234        assert!(!LarkErrorCode::InternalServerError.is_client_error());
1235        assert!(!LarkErrorCode::UserNotFound.is_client_error()); // 60001 不在400-499范围
1236    }
1237
1238    #[test]
1239    fn test_server_error_range() {
1240        // 测试所有HTTP服务器错误(500-599)
1241        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        // 确保非服务器错误不被误判
1247        assert!(!LarkErrorCode::Success.is_server_error());
1248        assert!(!LarkErrorCode::BadRequest.is_server_error());
1249        assert!(!LarkErrorCode::UserNotFound.is_server_error()); // 60001 不在500-599范围
1250        assert!(!LarkErrorCode::NetworkTimeout.is_server_error()); // 999001 不在500-599范围
1251    }
1252
1253    #[test]
1254    fn test_all_retryable_errors() {
1255        // 测试所有可重试错误
1256        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        // 确保不可重试错误不被误判
1266        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        // 测试所有重试延迟
1278        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        // 测试无重试延迟的错误
1309        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        // 测试有帮助链接的错误
1321        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        // 测试默认帮助链接
1339        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        // Info级别
1348        assert_eq!(LarkErrorCode::Success.severity(), ErrorSeverity::Info);
1349
1350        // Warning级别
1351        assert_eq!(
1352            LarkErrorCode::TooManyRequests.severity(),
1353            ErrorSeverity::Warning
1354        );
1355
1356        // Error级别
1357        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        // Critical级别
1363        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        // 其他错误默认为Warning
1377        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        // 测试Display trait的实现
1394        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        // 测试ErrorCategory的基本trait
1408        let category = ErrorCategory::Authentication;
1409
1410        // 测试Debug
1411        let debug_str = format!("{:?}", category);
1412        assert!(debug_str.contains("Authentication"));
1413
1414        // 测试Clone和Copy
1415        let cloned = category;
1416        assert_eq!(category, cloned);
1417
1418        // 测试PartialEq和Eq
1419        assert_eq!(ErrorCategory::Authentication, ErrorCategory::Authentication);
1420        assert_ne!(ErrorCategory::Authentication, ErrorCategory::Permission);
1421
1422        // 测试Hash(通过将其放入HashMap验证)
1423        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        // 测试LarkErrorCode的基本trait
1432        let error = LarkErrorCode::BadRequest;
1433
1434        // 测试Debug
1435        let debug_str = format!("{:?}", error);
1436        assert!(debug_str.contains("BadRequest"));
1437
1438        // 测试Clone和Copy
1439        let cloned = error;
1440        assert_eq!(error, cloned);
1441
1442        // 测试PartialEq和Eq
1443        assert_eq!(LarkErrorCode::BadRequest, LarkErrorCode::BadRequest);
1444        assert_ne!(LarkErrorCode::BadRequest, LarkErrorCode::NotFound);
1445
1446        // 测试Hash(通过将其放入HashMap验证)
1447        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        // 测试边界情况
1456
1457        // 测试最大和最小的错误码
1458        assert_eq!(LarkErrorCode::from_code(0), Some(LarkErrorCode::Success));
1459        assert_eq!(
1460            LarkErrorCode::from_code(99991671),
1461            Some(LarkErrorCode::AccessTokenInvalid)
1462        );
1463
1464        // 测试负数错误码
1465        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        // 测试HTTP状态码边界
1470        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}