Skip to main content

wae_types/
error.rs

1//! 中心化错误类型定义
2//!
3//! 提供统一的错误处理机制,支持国际化。
4
5use serde::{Deserialize, Serialize};
6use serde_json::{Value, json};
7use std::fmt;
8
9/// WAE 结果类型
10pub type WaeResult<T> = Result<T, WaeError>;
11
12/// 中心化错误类型
13///
14/// 包含错误类型标识,支持国际化。
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct WaeError {
17    /// 错误类型
18    pub kind: Box<WaeErrorKind>,
19}
20
21/// 错误分类
22///
23/// 用于将错误映射到 HTTP 状态码等场景。
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
25pub enum ErrorCategory {
26    /// 验证错误 (400)
27    Validation,
28    /// 认证错误 (401)
29    Auth,
30    /// 权限错误 (403)
31    Permission,
32    /// 资源未找到 (404)
33    NotFound,
34    /// 请求冲突 (409)
35    Conflict,
36    /// 请求过多 (429)
37    RateLimited,
38    /// 网络/服务错误 (502/503)
39    Network,
40    /// 存储错误 (500)
41    Storage,
42    /// 数据库错误 (500)
43    Database,
44    /// 缓存错误 (500)
45    Cache,
46    /// 配置错误 (500)
47    Config,
48    /// 超时错误 (408/504)
49    Timeout,
50    /// 内部错误 (500)
51    Internal,
52}
53
54impl ErrorCategory {
55    /// 获取对应的 HTTP 状态码
56    pub fn http_status(&self) -> u16 {
57        match self {
58            ErrorCategory::Validation => 400,
59            ErrorCategory::Auth => 401,
60            ErrorCategory::Permission => 403,
61            ErrorCategory::NotFound => 404,
62            ErrorCategory::Conflict => 409,
63            ErrorCategory::RateLimited => 429,
64            ErrorCategory::Network => 502,
65            ErrorCategory::Storage => 500,
66            ErrorCategory::Database => 500,
67            ErrorCategory::Cache => 500,
68            ErrorCategory::Config => 500,
69            ErrorCategory::Timeout => 408,
70            ErrorCategory::Internal => 500,
71        }
72    }
73}
74
75/// 统一错误类型枚举
76///
77/// 整合所有模块的错误变体,每个变体对应一个 i18n key。
78#[derive(Debug, Clone, Serialize, Deserialize)]
79pub enum WaeErrorKind {
80    // ========== 验证错误 ==========
81    /// 无效格式
82    InvalidFormat {
83        /// 字段名
84        field: String,
85        /// 期望格式
86        expected: String,
87    },
88    /// 值超出范围
89    OutOfRange {
90        /// 字段名
91        field: String,
92        /// 最小值
93        min: Option<String>,
94        /// 最大值
95        max: Option<String>,
96    },
97    /// 必填字段缺失
98    Required {
99        /// 字段名
100        field: String,
101    },
102    /// 值已存在
103    AlreadyExists {
104        /// 字段名
105        field: String,
106        /// 值
107        value: String,
108    },
109    /// 值不允许
110    NotAllowed {
111        /// 字段名
112        field: String,
113        /// 允许的值
114        allowed: Vec<String>,
115    },
116    /// 无效参数
117    InvalidParams {
118        /// 参数名
119        param: String,
120        /// 原因
121        reason: String,
122    },
123
124    // ========== 认证错误 (Auth) ==========
125    /// 无效凭证
126    InvalidCredentials,
127    /// 账户已锁定
128    AccountLocked,
129    /// 用户未找到
130    UserNotFound {
131        /// 用户标识
132        identifier: String,
133    },
134    /// 用户已存在
135    UserAlreadyExists {
136        /// 用户名
137        username: String,
138    },
139    /// 无效令牌
140    InvalidToken {
141        /// 原因
142        reason: String,
143    },
144    /// 令牌已过期
145    TokenExpired,
146    /// 令牌尚未生效
147    TokenNotValidYet,
148    /// 无效签名
149    InvalidSignature,
150    /// 无效算法
151    InvalidAlgorithm,
152    /// 缺少声明
153    MissingClaim {
154        /// 声明名
155        claim: String,
156    },
157    /// 无效声明
158    InvalidClaim {
159        /// 声明名
160        claim: String,
161    },
162    /// 无效签发者
163    InvalidIssuer {
164        /// 期望值
165        expected: String,
166        /// 实际值
167        actual: String,
168    },
169    /// 无效受众
170    InvalidAudience,
171    /// 密钥错误
172    KeyError,
173    /// 编码错误
174    EncodingError,
175    /// 解码错误
176    DecodingError,
177
178    // ========== OAuth2 错误 ==========
179    /// 无效授权码
180    InvalidAuthorizationCode,
181    /// 无效重定向 URI
182    InvalidRedirectUri,
183    /// 无效客户端 ID
184    InvalidClientId,
185    /// 无效客户端密钥
186    InvalidClientSecret,
187    /// 无效授权范围
188    InvalidScope {
189        /// 范围
190        scope: String,
191    },
192    /// 无效访问令牌
193    InvalidAccessToken,
194    /// 无效刷新令牌
195    InvalidRefreshToken,
196    /// 访问被拒绝
197    AccessDenied {
198        /// 原因
199        reason: String,
200    },
201    /// 不支持的授权类型
202    UnsupportedGrantType {
203        /// 类型
204        grant_type: String,
205    },
206    /// 不支持的响应类型
207    UnsupportedResponseType {
208        /// 类型
209        response_type: String,
210    },
211    /// 状态不匹配
212    StateMismatch,
213    /// OAuth2 提供者错误
214    OAuth2ProviderError {
215        /// 错误信息
216        message: String,
217    },
218
219    // ========== SAML 错误 ==========
220    /// 无效 SAML 请求
221    InvalidSamlRequest {
222        /// 原因
223        reason: String,
224    },
225    /// 无效 SAML 响应
226    InvalidSamlResponse {
227        /// 原因
228        reason: String,
229    },
230    /// 无效断言
231    InvalidAssertion {
232        /// 原因
233        reason: String,
234    },
235    /// 签名验证失败
236    SignatureVerificationFailed {
237        /// 原因
238        reason: String,
239    },
240    /// 缺少签名
241    MissingSignature,
242    /// 证书错误
243    CertificateError {
244        /// 原因
245        reason: String,
246    },
247    /// XML 解析错误
248    XmlParsingError {
249        /// 原因
250        reason: String,
251    },
252    /// Base64 解码错误
253    Base64DecodeError {
254        /// 原因
255        reason: String,
256    },
257    /// 压缩错误
258    CompressionError {
259        /// 原因
260        reason: String,
261    },
262    /// 断言已过期
263    AssertionExpired,
264    /// 断言尚未生效
265    AssertionNotYetValid,
266    /// 受众验证失败
267    SamlAudienceValidationFailed {
268        /// 期望值
269        expected: String,
270        /// 实际值
271        actual: String,
272    },
273    /// 发行人验证失败
274    SamlIssuerValidationFailed {
275        /// 期望值
276        expected: String,
277        /// 实际值
278        actual: String,
279    },
280    /// 目标验证失败
281    DestinationValidationFailed,
282    /// 重放攻击检测
283    ReplayAttackDetected,
284    /// 不支持的绑定
285    UnsupportedBinding {
286        /// 绑定类型
287        binding: String,
288    },
289    /// 不支持的名称 ID 格式
290    UnsupportedNameIdFormat {
291        /// 格式
292        format: String,
293    },
294
295    // ========== TOTP 错误 ==========
296    /// 无效密钥
297    InvalidSecret {
298        /// 原因
299        reason: String,
300    },
301    /// 无体验证码
302    InvalidCode,
303    /// 验证码已过期
304    CodeExpired,
305    /// 验证码格式错误
306    InvalidCodeFormat {
307        /// 期望位数
308        expected: usize,
309        /// 实际位数
310        actual: usize,
311    },
312    /// 无效时间步长
313    InvalidTimeStep,
314    /// Base32 错误
315    Base32Error {
316        /// 原因
317        reason: String,
318    },
319    /// HMAC 错误
320    HmacError {
321        /// 原因
322        reason: String,
323    },
324    /// QR 码错误
325    QrCodeError {
326        /// 原因
327        reason: String,
328    },
329
330    // ========== 权限错误 ==========
331    /// 权限拒绝
332    PermissionDenied {
333        /// 操作
334        action: String,
335    },
336    /// 禁止访问
337    Forbidden {
338        /// 资源
339        resource: String,
340    },
341
342    // ========== 资源未找到 ==========
343    /// 资源未找到
344    ResourceNotFound {
345        /// 资源类型
346        resource_type: String,
347        /// 资源标识
348        identifier: String,
349    },
350
351    // ========== 冲突错误 ==========
352    /// 资源冲突
353    ResourceConflict {
354        /// 资源
355        resource: String,
356        /// 原因
357        reason: String,
358    },
359
360    // ========== 网络错误 ==========
361    /// 连接失败
362    ConnectionFailed {
363        /// 目标
364        target: String,
365    },
366    /// DNS 解析失败
367    DnsResolutionFailed {
368        /// 主机
369        host: String,
370    },
371    /// TLS 错误
372    TlsError {
373        /// 原因
374        reason: String,
375    },
376    /// 协议错误
377    ProtocolError {
378        /// 协议
379        protocol: String,
380        /// 原因
381        reason: String,
382    },
383    /// 服务不可用
384    ServiceUnavailable {
385        /// 服务名
386        service: String,
387    },
388    /// 网关错误
389    GatewayError {
390        /// 网关
391        gateway: String,
392    },
393
394    // ========== 存储错误 ==========
395    /// 读取失败
396    StorageReadFailed {
397        /// 路径
398        path: String,
399    },
400    /// 写入失败
401    StorageWriteFailed {
402        /// 路径
403        path: String,
404    },
405    /// 删除失败
406    StorageDeleteFailed {
407        /// 路径
408        path: String,
409    },
410    /// 容量不足
411    InsufficientCapacity {
412        /// 需要
413        required: u64,
414        /// 可用
415        available: u64,
416    },
417    /// 数据损坏
418    DataCorruption {
419        /// 位置
420        location: String,
421    },
422    /// 文件未找到
423    StorageFileNotFound {
424        /// 路径
425        path: String,
426    },
427
428    // ========== 数据库错误 ==========
429    /// 数据库连接失败
430    DatabaseConnectionFailed {
431        /// 原因
432        reason: String,
433    },
434    /// 查询失败
435    QueryFailed {
436        /// 查询语句
437        query: Option<String>,
438        /// 原因
439        reason: String,
440    },
441    /// 执行失败
442    ExecuteFailed {
443        /// 语句
444        statement: Option<String>,
445        /// 原因
446        reason: String,
447    },
448    /// 事务失败
449    TransactionFailed {
450        /// 原因
451        reason: String,
452    },
453    /// 迁移失败
454    MigrationFailed {
455        /// 版本
456        version: Option<String>,
457        /// 原因
458        reason: String,
459    },
460
461    // ========== 缓存错误 ==========
462    /// 缓存连接失败
463    CacheConnectionFailed {
464        /// 原因
465        reason: String,
466    },
467    /// 缓存键不存在
468    CacheKeyNotFound {
469        /// 键
470        key: String,
471    },
472    /// 序列化失败
473    SerializationFailed {
474        /// 类型
475        type_name: String,
476    },
477    /// 反序列化失败
478    DeserializationFailed {
479        /// 类型
480        type_name: String,
481    },
482
483    // ========== 弹性容错错误 ==========
484    /// 熔断器开启
485    CircuitBreakerOpen {
486        /// 服务名
487        service: String,
488    },
489    /// 限流超出
490    RateLimitExceeded {
491        /// 限制
492        limit: u64,
493    },
494    /// 重试次数耗尽
495    MaxRetriesExceeded {
496        /// 次数
497        attempts: u32,
498    },
499    /// 舱壁已满
500    BulkheadFull {
501        /// 最大并发
502        max_concurrent: usize,
503    },
504    /// 舱壁等待超时
505    BulkheadWaitTimeout,
506
507    // ========== 调度器错误 ==========
508    /// 任务未找到
509    TaskNotFound {
510        /// 任务 ID
511        task_id: String,
512    },
513    /// 任务已存在
514    TaskAlreadyExists {
515        /// 任务 ID
516        task_id: String,
517    },
518    /// 无效 Cron 表达式
519    InvalidCronExpression {
520        /// 表达式
521        expression: String,
522    },
523    /// 任务执行失败
524    TaskExecutionFailed {
525        /// 任务 ID
526        task_id: String,
527        /// 原因
528        reason: String,
529    },
530    /// 调度器已关闭
531    SchedulerShutdown,
532
533    // ========== 测试错误 ==========
534    /// Mock 错误
535    MockError {
536        /// 原因
537        reason: String,
538    },
539    /// 断言失败
540    AssertionFailed {
541        /// 消息
542        message: String,
543    },
544    /// Fixture 错误
545    FixtureError {
546        /// 原因
547        reason: String,
548    },
549    /// 环境错误
550    EnvironmentError {
551        /// 原因
552        reason: String,
553    },
554
555    // ========== 超时错误 ==========
556    /// 操作超时
557    OperationTimeout {
558        /// 操作名
559        operation: String,
560        /// 超时时间(毫秒)
561        timeout_ms: u64,
562    },
563
564    // ========== 配置错误 ==========
565    /// 配置缺失
566    ConfigMissing {
567        /// 配置键
568        key: String,
569    },
570    /// 配置无效
571    ConfigInvalid {
572        /// 配置键
573        key: String,
574        /// 原因
575        reason: String,
576    },
577
578    // ========== 内部错误 ==========
579    /// 内部错误
580    InternalError {
581        /// 原因
582        reason: String,
583    },
584    /// 未实现
585    NotImplemented {
586        /// 功能
587        feature: String,
588    },
589    /// IO 错误
590    IoError {
591        /// 操作
592        operation: String,
593        /// 原因
594        reason: String,
595    },
596    /// JSON 错误
597    JsonError {
598        /// 原因
599        reason: String,
600    },
601    /// 解析错误
602    ParseError {
603        /// 类型
604        type_name: String,
605        /// 原因
606        reason: String,
607    },
608    /// 请求错误
609    RequestError {
610        /// URL
611        url: String,
612        /// 原因
613        reason: String,
614    },
615}
616
617impl WaeErrorKind {
618    /// 获取错误分类
619    pub fn category(&self) -> ErrorCategory {
620        match self {
621            WaeErrorKind::InvalidFormat { .. }
622            | WaeErrorKind::OutOfRange { .. }
623            | WaeErrorKind::Required { .. }
624            | WaeErrorKind::AlreadyExists { .. }
625            | WaeErrorKind::NotAllowed { .. }
626            | WaeErrorKind::InvalidParams { .. } => ErrorCategory::Validation,
627
628            WaeErrorKind::InvalidCredentials
629            | WaeErrorKind::AccountLocked
630            | WaeErrorKind::UserNotFound { .. }
631            | WaeErrorKind::UserAlreadyExists { .. }
632            | WaeErrorKind::InvalidToken { .. }
633            | WaeErrorKind::TokenExpired
634            | WaeErrorKind::TokenNotValidYet
635            | WaeErrorKind::InvalidSignature
636            | WaeErrorKind::InvalidAlgorithm
637            | WaeErrorKind::MissingClaim { .. }
638            | WaeErrorKind::InvalidClaim { .. }
639            | WaeErrorKind::InvalidIssuer { .. }
640            | WaeErrorKind::InvalidAudience
641            | WaeErrorKind::KeyError
642            | WaeErrorKind::EncodingError
643            | WaeErrorKind::DecodingError
644            | WaeErrorKind::InvalidAuthorizationCode
645            | WaeErrorKind::InvalidRedirectUri
646            | WaeErrorKind::InvalidClientId
647            | WaeErrorKind::InvalidClientSecret
648            | WaeErrorKind::InvalidScope { .. }
649            | WaeErrorKind::InvalidAccessToken
650            | WaeErrorKind::InvalidRefreshToken
651            | WaeErrorKind::AccessDenied { .. }
652            | WaeErrorKind::UnsupportedGrantType { .. }
653            | WaeErrorKind::UnsupportedResponseType { .. }
654            | WaeErrorKind::StateMismatch
655            | WaeErrorKind::OAuth2ProviderError { .. }
656            | WaeErrorKind::InvalidSamlRequest { .. }
657            | WaeErrorKind::InvalidSamlResponse { .. }
658            | WaeErrorKind::InvalidAssertion { .. }
659            | WaeErrorKind::SignatureVerificationFailed { .. }
660            | WaeErrorKind::MissingSignature
661            | WaeErrorKind::CertificateError { .. }
662            | WaeErrorKind::XmlParsingError { .. }
663            | WaeErrorKind::Base64DecodeError { .. }
664            | WaeErrorKind::CompressionError { .. }
665            | WaeErrorKind::AssertionExpired
666            | WaeErrorKind::AssertionNotYetValid
667            | WaeErrorKind::SamlAudienceValidationFailed { .. }
668            | WaeErrorKind::SamlIssuerValidationFailed { .. }
669            | WaeErrorKind::DestinationValidationFailed
670            | WaeErrorKind::ReplayAttackDetected
671            | WaeErrorKind::UnsupportedBinding { .. }
672            | WaeErrorKind::UnsupportedNameIdFormat { .. }
673            | WaeErrorKind::InvalidSecret { .. }
674            | WaeErrorKind::InvalidCode
675            | WaeErrorKind::CodeExpired
676            | WaeErrorKind::InvalidCodeFormat { .. }
677            | WaeErrorKind::InvalidTimeStep
678            | WaeErrorKind::Base32Error { .. }
679            | WaeErrorKind::HmacError { .. }
680            | WaeErrorKind::QrCodeError { .. } => ErrorCategory::Auth,
681
682            WaeErrorKind::PermissionDenied { .. } | WaeErrorKind::Forbidden { .. } => ErrorCategory::Permission,
683
684            WaeErrorKind::ResourceNotFound { .. } => ErrorCategory::NotFound,
685
686            WaeErrorKind::ResourceConflict { .. } => ErrorCategory::Conflict,
687
688            WaeErrorKind::RateLimitExceeded { .. } => ErrorCategory::RateLimited,
689
690            WaeErrorKind::ConnectionFailed { .. }
691            | WaeErrorKind::DnsResolutionFailed { .. }
692            | WaeErrorKind::TlsError { .. }
693            | WaeErrorKind::ProtocolError { .. }
694            | WaeErrorKind::ServiceUnavailable { .. }
695            | WaeErrorKind::GatewayError { .. } => ErrorCategory::Network,
696
697            WaeErrorKind::StorageReadFailed { .. }
698            | WaeErrorKind::StorageWriteFailed { .. }
699            | WaeErrorKind::StorageDeleteFailed { .. }
700            | WaeErrorKind::InsufficientCapacity { .. }
701            | WaeErrorKind::DataCorruption { .. }
702            | WaeErrorKind::StorageFileNotFound { .. } => ErrorCategory::Storage,
703
704            WaeErrorKind::DatabaseConnectionFailed { .. }
705            | WaeErrorKind::QueryFailed { .. }
706            | WaeErrorKind::ExecuteFailed { .. }
707            | WaeErrorKind::TransactionFailed { .. }
708            | WaeErrorKind::MigrationFailed { .. } => ErrorCategory::Database,
709
710            WaeErrorKind::CacheConnectionFailed { .. }
711            | WaeErrorKind::CacheKeyNotFound { .. }
712            | WaeErrorKind::SerializationFailed { .. }
713            | WaeErrorKind::DeserializationFailed { .. } => ErrorCategory::Cache,
714
715            WaeErrorKind::CircuitBreakerOpen { .. } | WaeErrorKind::BulkheadFull { .. } | WaeErrorKind::BulkheadWaitTimeout => {
716                ErrorCategory::Network
717            }
718
719            WaeErrorKind::MaxRetriesExceeded { .. } => ErrorCategory::Network,
720
721            WaeErrorKind::TaskNotFound { .. }
722            | WaeErrorKind::TaskAlreadyExists { .. }
723            | WaeErrorKind::InvalidCronExpression { .. }
724            | WaeErrorKind::TaskExecutionFailed { .. }
725            | WaeErrorKind::SchedulerShutdown => ErrorCategory::Internal,
726
727            WaeErrorKind::MockError { .. }
728            | WaeErrorKind::AssertionFailed { .. }
729            | WaeErrorKind::FixtureError { .. }
730            | WaeErrorKind::EnvironmentError { .. } => ErrorCategory::Internal,
731
732            WaeErrorKind::OperationTimeout { .. } => ErrorCategory::Timeout,
733
734            WaeErrorKind::ConfigMissing { .. } | WaeErrorKind::ConfigInvalid { .. } => ErrorCategory::Config,
735
736            WaeErrorKind::InternalError { .. }
737            | WaeErrorKind::NotImplemented { .. }
738            | WaeErrorKind::IoError { .. }
739            | WaeErrorKind::JsonError { .. }
740            | WaeErrorKind::ParseError { .. }
741            | WaeErrorKind::RequestError { .. } => ErrorCategory::Internal,
742        }
743    }
744
745    /// 获取国际化键
746    pub fn i18n_key(&self) -> &'static str {
747        match self {
748            WaeErrorKind::InvalidFormat { .. } => "wae.error.validation.invalid_format",
749            WaeErrorKind::OutOfRange { .. } => "wae.error.validation.out_of_range",
750            WaeErrorKind::Required { .. } => "wae.error.validation.required",
751            WaeErrorKind::AlreadyExists { .. } => "wae.error.validation.already_exists",
752            WaeErrorKind::NotAllowed { .. } => "wae.error.validation.not_allowed",
753            WaeErrorKind::InvalidParams { .. } => "wae.error.validation.invalid_params",
754
755            WaeErrorKind::InvalidCredentials => "wae.error.auth.invalid_credentials",
756            WaeErrorKind::AccountLocked => "wae.error.auth.account_locked",
757            WaeErrorKind::UserNotFound { .. } => "wae.error.auth.user_not_found",
758            WaeErrorKind::UserAlreadyExists { .. } => "wae.error.auth.user_already_exists",
759            WaeErrorKind::InvalidToken { .. } => "wae.error.auth.invalid_token",
760            WaeErrorKind::TokenExpired => "wae.error.auth.token_expired",
761            WaeErrorKind::TokenNotValidYet => "wae.error.auth.token_not_valid_yet",
762            WaeErrorKind::InvalidSignature => "wae.error.auth.invalid_signature",
763            WaeErrorKind::InvalidAlgorithm => "wae.error.auth.invalid_algorithm",
764            WaeErrorKind::MissingClaim { .. } => "wae.error.auth.missing_claim",
765            WaeErrorKind::InvalidClaim { .. } => "wae.error.auth.invalid_claim",
766            WaeErrorKind::InvalidIssuer { .. } => "wae.error.auth.invalid_issuer",
767            WaeErrorKind::InvalidAudience => "wae.error.auth.invalid_audience",
768            WaeErrorKind::KeyError => "wae.error.auth.key_error",
769            WaeErrorKind::EncodingError => "wae.error.auth.encoding_error",
770            WaeErrorKind::DecodingError => "wae.error.auth.decoding_error",
771
772            WaeErrorKind::InvalidAuthorizationCode => "wae.error.oauth2.invalid_authorization_code",
773            WaeErrorKind::InvalidRedirectUri => "wae.error.oauth2.invalid_redirect_uri",
774            WaeErrorKind::InvalidClientId => "wae.error.oauth2.invalid_client_id",
775            WaeErrorKind::InvalidClientSecret => "wae.error.oauth2.invalid_client_secret",
776            WaeErrorKind::InvalidScope { .. } => "wae.error.oauth2.invalid_scope",
777            WaeErrorKind::InvalidAccessToken => "wae.error.oauth2.invalid_access_token",
778            WaeErrorKind::InvalidRefreshToken => "wae.error.oauth2.invalid_refresh_token",
779            WaeErrorKind::AccessDenied { .. } => "wae.error.oauth2.access_denied",
780            WaeErrorKind::UnsupportedGrantType { .. } => "wae.error.oauth2.unsupported_grant_type",
781            WaeErrorKind::UnsupportedResponseType { .. } => "wae.error.oauth2.unsupported_response_type",
782            WaeErrorKind::StateMismatch => "wae.error.oauth2.state_mismatch",
783            WaeErrorKind::OAuth2ProviderError { .. } => "wae.error.oauth2.provider_error",
784
785            WaeErrorKind::InvalidSamlRequest { .. } => "wae.error.saml.invalid_request",
786            WaeErrorKind::InvalidSamlResponse { .. } => "wae.error.saml.invalid_response",
787            WaeErrorKind::InvalidAssertion { .. } => "wae.error.saml.invalid_assertion",
788            WaeErrorKind::SignatureVerificationFailed { .. } => "wae.error.saml.signature_verification_failed",
789            WaeErrorKind::MissingSignature => "wae.error.saml.missing_signature",
790            WaeErrorKind::CertificateError { .. } => "wae.error.saml.certificate_error",
791            WaeErrorKind::XmlParsingError { .. } => "wae.error.saml.xml_parsing_error",
792            WaeErrorKind::Base64DecodeError { .. } => "wae.error.saml.base64_decode_error",
793            WaeErrorKind::CompressionError { .. } => "wae.error.saml.compression_error",
794            WaeErrorKind::AssertionExpired => "wae.error.saml.assertion_expired",
795            WaeErrorKind::AssertionNotYetValid => "wae.error.saml.assertion_not_yet_valid",
796            WaeErrorKind::SamlAudienceValidationFailed { .. } => "wae.error.saml.audience_validation_failed",
797            WaeErrorKind::SamlIssuerValidationFailed { .. } => "wae.error.saml.issuer_validation_failed",
798            WaeErrorKind::DestinationValidationFailed => "wae.error.saml.destination_validation_failed",
799            WaeErrorKind::ReplayAttackDetected => "wae.error.saml.replay_attack_detected",
800            WaeErrorKind::UnsupportedBinding { .. } => "wae.error.saml.unsupported_binding",
801            WaeErrorKind::UnsupportedNameIdFormat { .. } => "wae.error.saml.unsupported_name_id_format",
802
803            WaeErrorKind::InvalidSecret { .. } => "wae.error.totp.invalid_secret",
804            WaeErrorKind::InvalidCode => "wae.error.totp.invalid_code",
805            WaeErrorKind::CodeExpired => "wae.error.totp.code_expired",
806            WaeErrorKind::InvalidCodeFormat { .. } => "wae.error.totp.invalid_code_format",
807            WaeErrorKind::InvalidTimeStep => "wae.error.totp.invalid_time_step",
808            WaeErrorKind::Base32Error { .. } => "wae.error.totp.base32_error",
809            WaeErrorKind::HmacError { .. } => "wae.error.totp.hmac_error",
810            WaeErrorKind::QrCodeError { .. } => "wae.error.totp.qr_code_error",
811
812            WaeErrorKind::PermissionDenied { .. } => "wae.error.permission.denied",
813            WaeErrorKind::Forbidden { .. } => "wae.error.permission.forbidden",
814
815            WaeErrorKind::ResourceNotFound { .. } => "wae.error.not_found.resource",
816
817            WaeErrorKind::ResourceConflict { .. } => "wae.error.conflict.resource",
818
819            WaeErrorKind::RateLimitExceeded { .. } => "wae.error.rate_limited",
820
821            WaeErrorKind::ConnectionFailed { .. } => "wae.error.network.connection_failed",
822            WaeErrorKind::DnsResolutionFailed { .. } => "wae.error.network.dns_resolution_failed",
823            WaeErrorKind::TlsError { .. } => "wae.error.network.tls_error",
824            WaeErrorKind::ProtocolError { .. } => "wae.error.network.protocol_error",
825            WaeErrorKind::ServiceUnavailable { .. } => "wae.error.network.service_unavailable",
826            WaeErrorKind::GatewayError { .. } => "wae.error.network.gateway_error",
827
828            WaeErrorKind::StorageReadFailed { .. } => "wae.error.storage.read_failed",
829            WaeErrorKind::StorageWriteFailed { .. } => "wae.error.storage.write_failed",
830            WaeErrorKind::StorageDeleteFailed { .. } => "wae.error.storage.delete_failed",
831            WaeErrorKind::InsufficientCapacity { .. } => "wae.error.storage.insufficient_capacity",
832            WaeErrorKind::DataCorruption { .. } => "wae.error.storage.data_corruption",
833            WaeErrorKind::StorageFileNotFound { .. } => "wae.error.storage.file_not_found",
834
835            WaeErrorKind::DatabaseConnectionFailed { .. } => "wae.error.database.connection_failed",
836            WaeErrorKind::QueryFailed { .. } => "wae.error.database.query_failed",
837            WaeErrorKind::ExecuteFailed { .. } => "wae.error.database.execute_failed",
838            WaeErrorKind::TransactionFailed { .. } => "wae.error.database.transaction_failed",
839            WaeErrorKind::MigrationFailed { .. } => "wae.error.database.migration_failed",
840
841            WaeErrorKind::CacheConnectionFailed { .. } => "wae.error.cache.connection_failed",
842            WaeErrorKind::CacheKeyNotFound { .. } => "wae.error.cache.key_not_found",
843            WaeErrorKind::SerializationFailed { .. } => "wae.error.cache.serialization_failed",
844            WaeErrorKind::DeserializationFailed { .. } => "wae.error.cache.deserialization_failed",
845
846            WaeErrorKind::CircuitBreakerOpen { .. } => "wae.error.resilience.circuit_breaker_open",
847            WaeErrorKind::MaxRetriesExceeded { .. } => "wae.error.resilience.max_retries_exceeded",
848            WaeErrorKind::BulkheadFull { .. } => "wae.error.resilience.bulkhead_full",
849            WaeErrorKind::BulkheadWaitTimeout => "wae.error.resilience.bulkhead_wait_timeout",
850
851            WaeErrorKind::TaskNotFound { .. } => "wae.error.scheduler.task_not_found",
852            WaeErrorKind::TaskAlreadyExists { .. } => "wae.error.scheduler.task_already_exists",
853            WaeErrorKind::InvalidCronExpression { .. } => "wae.error.scheduler.invalid_cron_expression",
854            WaeErrorKind::TaskExecutionFailed { .. } => "wae.error.scheduler.task_execution_failed",
855            WaeErrorKind::SchedulerShutdown => "wae.error.scheduler.shutdown",
856
857            WaeErrorKind::MockError { .. } => "wae.error.testing.mock_error",
858            WaeErrorKind::AssertionFailed { .. } => "wae.error.testing.assertion_failed",
859            WaeErrorKind::FixtureError { .. } => "wae.error.testing.fixture_error",
860            WaeErrorKind::EnvironmentError { .. } => "wae.error.testing.environment_error",
861
862            WaeErrorKind::OperationTimeout { .. } => "wae.error.timeout.operation",
863
864            WaeErrorKind::ConfigMissing { .. } => "wae.error.config.missing",
865            WaeErrorKind::ConfigInvalid { .. } => "wae.error.config.invalid",
866
867            WaeErrorKind::InternalError { .. } => "wae.error.internal.error",
868            WaeErrorKind::NotImplemented { .. } => "wae.error.internal.not_implemented",
869            WaeErrorKind::IoError { .. } => "wae.error.internal.io_error",
870            WaeErrorKind::JsonError { .. } => "wae.error.internal.json_error",
871            WaeErrorKind::ParseError { .. } => "wae.error.internal.parse_error",
872            WaeErrorKind::RequestError { .. } => "wae.error.internal.request_error",
873        }
874    }
875
876    /// 获取国际化数据
877    pub fn i18n_data(&self) -> Value {
878        match self {
879            WaeErrorKind::InvalidFormat { field, expected } => {
880                json!({ "field": field, "expected": expected })
881            }
882            WaeErrorKind::OutOfRange { field, min, max } => {
883                json!({ "field": field, "min": min, "max": max })
884            }
885            WaeErrorKind::Required { field } => json!({ "field": field }),
886            WaeErrorKind::AlreadyExists { field, value } => json!({ "field": field, "value": value }),
887            WaeErrorKind::NotAllowed { field, allowed } => json!({ "field": field, "allowed": allowed }),
888            WaeErrorKind::InvalidParams { param, reason } => json!({ "param": param, "reason": reason }),
889
890            WaeErrorKind::InvalidCredentials => json!({}),
891            WaeErrorKind::AccountLocked => json!({}),
892            WaeErrorKind::UserNotFound { identifier } => json!({ "identifier": identifier }),
893            WaeErrorKind::UserAlreadyExists { username } => json!({ "username": username }),
894            WaeErrorKind::InvalidToken { reason } => json!({ "reason": reason }),
895            WaeErrorKind::TokenExpired => json!({}),
896            WaeErrorKind::TokenNotValidYet => json!({}),
897            WaeErrorKind::InvalidSignature => json!({}),
898            WaeErrorKind::InvalidAlgorithm => json!({}),
899            WaeErrorKind::MissingClaim { claim } => json!({ "claim": claim }),
900            WaeErrorKind::InvalidClaim { claim } => json!({ "claim": claim }),
901            WaeErrorKind::InvalidIssuer { expected, actual } => json!({ "expected": expected, "actual": actual }),
902            WaeErrorKind::InvalidAudience => json!({}),
903            WaeErrorKind::KeyError => json!({}),
904            WaeErrorKind::EncodingError => json!({}),
905            WaeErrorKind::DecodingError => json!({}),
906
907            WaeErrorKind::InvalidAuthorizationCode => json!({}),
908            WaeErrorKind::InvalidRedirectUri => json!({}),
909            WaeErrorKind::InvalidClientId => json!({}),
910            WaeErrorKind::InvalidClientSecret => json!({}),
911            WaeErrorKind::InvalidScope { scope } => json!({ "scope": scope }),
912            WaeErrorKind::InvalidAccessToken => json!({}),
913            WaeErrorKind::InvalidRefreshToken => json!({}),
914            WaeErrorKind::AccessDenied { reason } => json!({ "reason": reason }),
915            WaeErrorKind::UnsupportedGrantType { grant_type } => json!({ "grant_type": grant_type }),
916            WaeErrorKind::UnsupportedResponseType { response_type } => json!({ "response_type": response_type }),
917            WaeErrorKind::StateMismatch => json!({}),
918            WaeErrorKind::OAuth2ProviderError { message } => json!({ "message": message }),
919
920            WaeErrorKind::InvalidSamlRequest { reason } => json!({ "reason": reason }),
921            WaeErrorKind::InvalidSamlResponse { reason } => json!({ "reason": reason }),
922            WaeErrorKind::InvalidAssertion { reason } => json!({ "reason": reason }),
923            WaeErrorKind::SignatureVerificationFailed { reason } => json!({ "reason": reason }),
924            WaeErrorKind::MissingSignature => json!({}),
925            WaeErrorKind::CertificateError { reason } => json!({ "reason": reason }),
926            WaeErrorKind::XmlParsingError { reason } => json!({ "reason": reason }),
927            WaeErrorKind::Base64DecodeError { reason } => json!({ "reason": reason }),
928            WaeErrorKind::CompressionError { reason } => json!({ "reason": reason }),
929            WaeErrorKind::AssertionExpired => json!({}),
930            WaeErrorKind::AssertionNotYetValid => json!({}),
931            WaeErrorKind::SamlAudienceValidationFailed { expected, actual } => {
932                json!({ "expected": expected, "actual": actual })
933            }
934            WaeErrorKind::SamlIssuerValidationFailed { expected, actual } => {
935                json!({ "expected": expected, "actual": actual })
936            }
937            WaeErrorKind::DestinationValidationFailed => json!({}),
938            WaeErrorKind::ReplayAttackDetected => json!({}),
939            WaeErrorKind::UnsupportedBinding { binding } => json!({ "binding": binding }),
940            WaeErrorKind::UnsupportedNameIdFormat { format } => json!({ "format": format }),
941
942            WaeErrorKind::InvalidSecret { reason } => json!({ "reason": reason }),
943            WaeErrorKind::InvalidCode => json!({}),
944            WaeErrorKind::CodeExpired => json!({}),
945            WaeErrorKind::InvalidCodeFormat { expected, actual } => json!({ "expected": expected, "actual": actual }),
946            WaeErrorKind::InvalidTimeStep => json!({}),
947            WaeErrorKind::Base32Error { reason } => json!({ "reason": reason }),
948            WaeErrorKind::HmacError { reason } => json!({ "reason": reason }),
949            WaeErrorKind::QrCodeError { reason } => json!({ "reason": reason }),
950
951            WaeErrorKind::PermissionDenied { action } => json!({ "action": action }),
952            WaeErrorKind::Forbidden { resource } => json!({ "resource": resource }),
953
954            WaeErrorKind::ResourceNotFound { resource_type, identifier } => {
955                json!({ "resource_type": resource_type, "identifier": identifier })
956            }
957
958            WaeErrorKind::ResourceConflict { resource, reason } => json!({ "resource": resource, "reason": reason }),
959
960            WaeErrorKind::RateLimitExceeded { limit } => json!({ "limit": limit }),
961
962            WaeErrorKind::ConnectionFailed { target } => json!({ "target": target }),
963            WaeErrorKind::DnsResolutionFailed { host } => json!({ "host": host }),
964            WaeErrorKind::TlsError { reason } => json!({ "reason": reason }),
965            WaeErrorKind::ProtocolError { protocol, reason } => json!({ "protocol": protocol, "reason": reason }),
966            WaeErrorKind::ServiceUnavailable { service } => json!({ "service": service }),
967            WaeErrorKind::GatewayError { gateway } => json!({ "gateway": gateway }),
968
969            WaeErrorKind::StorageReadFailed { path } => json!({ "path": path }),
970            WaeErrorKind::StorageWriteFailed { path } => json!({ "path": path }),
971            WaeErrorKind::StorageDeleteFailed { path } => json!({ "path": path }),
972            WaeErrorKind::InsufficientCapacity { required, available } => {
973                json!({ "required": required, "available": available })
974            }
975            WaeErrorKind::DataCorruption { location } => json!({ "location": location }),
976            WaeErrorKind::StorageFileNotFound { path } => json!({ "path": path }),
977
978            WaeErrorKind::DatabaseConnectionFailed { reason } => json!({ "reason": reason }),
979            WaeErrorKind::QueryFailed { query, reason } => json!({ "query": query, "reason": reason }),
980            WaeErrorKind::ExecuteFailed { statement, reason } => json!({ "statement": statement, "reason": reason }),
981            WaeErrorKind::TransactionFailed { reason } => json!({ "reason": reason }),
982            WaeErrorKind::MigrationFailed { version, reason } => json!({ "version": version, "reason": reason }),
983
984            WaeErrorKind::CacheConnectionFailed { reason } => json!({ "reason": reason }),
985            WaeErrorKind::CacheKeyNotFound { key } => json!({ "key": key }),
986            WaeErrorKind::SerializationFailed { type_name } => json!({ "type": type_name }),
987            WaeErrorKind::DeserializationFailed { type_name } => json!({ "type": type_name }),
988
989            WaeErrorKind::CircuitBreakerOpen { service } => json!({ "service": service }),
990            WaeErrorKind::MaxRetriesExceeded { attempts } => json!({ "attempts": attempts }),
991            WaeErrorKind::BulkheadFull { max_concurrent } => json!({ "max_concurrent": max_concurrent }),
992            WaeErrorKind::BulkheadWaitTimeout => json!({}),
993
994            WaeErrorKind::TaskNotFound { task_id } => json!({ "task_id": task_id }),
995            WaeErrorKind::TaskAlreadyExists { task_id } => json!({ "task_id": task_id }),
996            WaeErrorKind::InvalidCronExpression { expression } => json!({ "expression": expression }),
997            WaeErrorKind::TaskExecutionFailed { task_id, reason } => json!({ "task_id": task_id, "reason": reason }),
998            WaeErrorKind::SchedulerShutdown => json!({}),
999
1000            WaeErrorKind::MockError { reason } => json!({ "reason": reason }),
1001            WaeErrorKind::AssertionFailed { message } => json!({ "message": message }),
1002            WaeErrorKind::FixtureError { reason } => json!({ "reason": reason }),
1003            WaeErrorKind::EnvironmentError { reason } => json!({ "reason": reason }),
1004
1005            WaeErrorKind::OperationTimeout { operation, timeout_ms } => {
1006                json!({ "operation": operation, "timeout_ms": timeout_ms })
1007            }
1008
1009            WaeErrorKind::ConfigMissing { key } => json!({ "key": key }),
1010            WaeErrorKind::ConfigInvalid { key, reason } => json!({ "key": key, "reason": reason }),
1011
1012            WaeErrorKind::InternalError { reason } => json!({ "reason": reason }),
1013            WaeErrorKind::NotImplemented { feature } => json!({ "feature": feature }),
1014            WaeErrorKind::IoError { operation, reason } => json!({ "operation": operation, "reason": reason }),
1015            WaeErrorKind::JsonError { reason } => json!({ "reason": reason }),
1016            WaeErrorKind::ParseError { type_name, reason } => json!({ "type": type_name, "reason": reason }),
1017            WaeErrorKind::RequestError { url, reason } => json!({ "url": url, "reason": reason }),
1018        }
1019    }
1020}
1021
1022impl fmt::Display for WaeErrorKind {
1023    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1024        write!(f, "{}", self.i18n_key())
1025    }
1026}
1027
1028impl WaeError {
1029    /// 创建新的错误
1030    pub fn new(kind: WaeErrorKind) -> Self {
1031        Self { kind: Box::new(kind) }
1032    }
1033
1034    /// 获取国际化键
1035    pub fn i18n_key(&self) -> &'static str {
1036        self.kind.i18n_key()
1037    }
1038
1039    /// 获取国际化数据
1040    pub fn i18n_data(&self) -> Value {
1041        self.kind.i18n_data()
1042    }
1043
1044    /// 获取错误分类
1045    pub fn category(&self) -> ErrorCategory {
1046        self.kind.category()
1047    }
1048
1049    /// 获取 HTTP 状态码
1050    pub fn http_status(&self) -> u16 {
1051        self.category().http_status()
1052    }
1053
1054    // ========== 验证错误便捷方法 ==========
1055
1056    /// 创建无效格式错误
1057    pub fn invalid_format(field: impl Into<String>, expected: impl Into<String>) -> Self {
1058        Self::new(WaeErrorKind::InvalidFormat { field: field.into(), expected: expected.into() })
1059    }
1060
1061    /// 创建超出范围错误
1062    pub fn out_of_range(field: impl Into<String>, min: Option<String>, max: Option<String>) -> Self {
1063        Self::new(WaeErrorKind::OutOfRange { field: field.into(), min, max })
1064    }
1065
1066    /// 创建必填字段缺失错误
1067    pub fn required(field: impl Into<String>) -> Self {
1068        Self::new(WaeErrorKind::Required { field: field.into() })
1069    }
1070
1071    /// 创建已存在错误
1072    pub fn already_exists(field: impl Into<String>, value: impl Into<String>) -> Self {
1073        Self::new(WaeErrorKind::AlreadyExists { field: field.into(), value: value.into() })
1074    }
1075
1076    /// 创建不允许错误
1077    pub fn not_allowed(field: impl Into<String>, allowed: Vec<String>) -> Self {
1078        Self::new(WaeErrorKind::NotAllowed { field: field.into(), allowed })
1079    }
1080
1081    /// 创建无效参数错误
1082    pub fn invalid_params(param: impl Into<String>, reason: impl Into<String>) -> Self {
1083        Self::new(WaeErrorKind::InvalidParams { param: param.into(), reason: reason.into() })
1084    }
1085
1086    // ========== 认证错误便捷方法 ==========
1087
1088    /// 创建无效凭证错误
1089    pub fn invalid_credentials() -> Self {
1090        Self::new(WaeErrorKind::InvalidCredentials)
1091    }
1092
1093    /// 创建账户已锁定错误
1094    pub fn account_locked() -> Self {
1095        Self::new(WaeErrorKind::AccountLocked)
1096    }
1097
1098    /// 创建用户未找到错误
1099    pub fn user_not_found(identifier: impl Into<String>) -> Self {
1100        Self::new(WaeErrorKind::UserNotFound { identifier: identifier.into() })
1101    }
1102
1103    /// 创建用户已存在错误
1104    pub fn user_already_exists(username: impl Into<String>) -> Self {
1105        Self::new(WaeErrorKind::UserAlreadyExists { username: username.into() })
1106    }
1107
1108    /// 创建无效令牌错误
1109    pub fn invalid_token(reason: impl Into<String>) -> Self {
1110        Self::new(WaeErrorKind::InvalidToken { reason: reason.into() })
1111    }
1112
1113    /// 创建令牌过期错误
1114    pub fn token_expired() -> Self {
1115        Self::new(WaeErrorKind::TokenExpired)
1116    }
1117
1118    /// 创建令牌尚未生效错误
1119    pub fn token_not_valid_yet() -> Self {
1120        Self::new(WaeErrorKind::TokenNotValidYet)
1121    }
1122
1123    /// 创建无效签名错误
1124    pub fn invalid_signature() -> Self {
1125        Self::new(WaeErrorKind::InvalidSignature)
1126    }
1127
1128    /// 创建缺少声明错误
1129    pub fn missing_claim(claim: impl Into<String>) -> Self {
1130        Self::new(WaeErrorKind::MissingClaim { claim: claim.into() })
1131    }
1132
1133    /// 创建无效声明错误
1134    pub fn invalid_claim(claim: impl Into<String>) -> Self {
1135        Self::new(WaeErrorKind::InvalidClaim { claim: claim.into() })
1136    }
1137
1138    /// 创建无效签发者错误
1139    pub fn invalid_issuer(expected: impl Into<String>, actual: impl Into<String>) -> Self {
1140        Self::new(WaeErrorKind::InvalidIssuer { expected: expected.into(), actual: actual.into() })
1141    }
1142
1143    /// 创建无效受众错误
1144    pub fn invalid_audience() -> Self {
1145        Self::new(WaeErrorKind::InvalidAudience)
1146    }
1147
1148    // ========== 权限错误便捷方法 ==========
1149
1150    /// 创建权限拒绝错误
1151    pub fn permission_denied(action: impl Into<String>) -> Self {
1152        Self::new(WaeErrorKind::PermissionDenied { action: action.into() })
1153    }
1154
1155    /// 创建禁止访问错误
1156    pub fn forbidden(resource: impl Into<String>) -> Self {
1157        Self::new(WaeErrorKind::Forbidden { resource: resource.into() })
1158    }
1159
1160    // ========== 资源未找到便捷方法 ==========
1161
1162    /// 创建资源未找到错误
1163    pub fn not_found(resource_type: impl Into<String>, identifier: impl Into<String>) -> Self {
1164        Self::new(WaeErrorKind::ResourceNotFound { resource_type: resource_type.into(), identifier: identifier.into() })
1165    }
1166
1167    // ========== 网络错误便捷方法 ==========
1168
1169    /// 创建连接失败错误
1170    pub fn connection_failed(target: impl Into<String>) -> Self {
1171        Self::new(WaeErrorKind::ConnectionFailed { target: target.into() })
1172    }
1173
1174    /// 创建服务不可用错误
1175    pub fn service_unavailable(service: impl Into<String>) -> Self {
1176        Self::new(WaeErrorKind::ServiceUnavailable { service: service.into() })
1177    }
1178
1179    // ========== 存储错误便捷方法 ==========
1180
1181    /// 创建存储读取失败错误
1182    pub fn storage_read_failed(path: impl Into<String>) -> Self {
1183        Self::new(WaeErrorKind::StorageReadFailed { path: path.into() })
1184    }
1185
1186    /// 创建存储写入失败错误
1187    pub fn storage_write_failed(path: impl Into<String>) -> Self {
1188        Self::new(WaeErrorKind::StorageWriteFailed { path: path.into() })
1189    }
1190
1191    /// 创建存储文件未找到错误
1192    pub fn storage_file_not_found(path: impl Into<String>) -> Self {
1193        Self::new(WaeErrorKind::StorageFileNotFound { path: path.into() })
1194    }
1195
1196    // ========== 数据库错误便捷方法 ==========
1197
1198    /// 创建数据库错误
1199    pub fn database(kind: WaeErrorKind) -> Self {
1200        Self::new(kind)
1201    }
1202
1203    /// 创建数据库连接失败错误
1204    pub fn database_connection_failed(reason: impl Into<String>) -> Self {
1205        Self::new(WaeErrorKind::DatabaseConnectionFailed { reason: reason.into() })
1206    }
1207
1208    /// 创建查询失败错误
1209    pub fn query_failed(query: Option<String>, reason: impl Into<String>) -> Self {
1210        Self::new(WaeErrorKind::QueryFailed { query, reason: reason.into() })
1211    }
1212
1213    /// 创建执行失败错误
1214    pub fn execute_failed(statement: Option<String>, reason: impl Into<String>) -> Self {
1215        Self::new(WaeErrorKind::ExecuteFailed { statement, reason: reason.into() })
1216    }
1217
1218    /// 创建事务失败错误
1219    pub fn transaction_failed(reason: impl Into<String>) -> Self {
1220        Self::new(WaeErrorKind::TransactionFailed { reason: reason.into() })
1221    }
1222
1223    // ========== 缓存错误便捷方法 ==========
1224
1225    /// 创建缓存键未找到错误
1226    pub fn cache_key_not_found(key: impl Into<String>) -> Self {
1227        Self::new(WaeErrorKind::CacheKeyNotFound { key: key.into() })
1228    }
1229
1230    /// 创建序列化失败错误
1231    pub fn serialization_failed(type_name: impl Into<String>) -> Self {
1232        Self::new(WaeErrorKind::SerializationFailed { type_name: type_name.into() })
1233    }
1234
1235    /// 创建反序列化失败错误
1236    pub fn deserialization_failed(type_name: impl Into<String>) -> Self {
1237        Self::new(WaeErrorKind::DeserializationFailed { type_name: type_name.into() })
1238    }
1239
1240    // ========== 弹性容错错误便捷方法 ==========
1241
1242    /// 创建熔断器开启错误
1243    pub fn circuit_breaker_open(service: impl Into<String>) -> Self {
1244        Self::new(WaeErrorKind::CircuitBreakerOpen { service: service.into() })
1245    }
1246
1247    /// 创建限流超出错误
1248    pub fn rate_limit_exceeded(limit: u64) -> Self {
1249        Self::new(WaeErrorKind::RateLimitExceeded { limit })
1250    }
1251
1252    /// 创建重试次数耗尽错误
1253    pub fn max_retries_exceeded(attempts: u32) -> Self {
1254        Self::new(WaeErrorKind::MaxRetriesExceeded { attempts })
1255    }
1256
1257    /// 创建舱壁已满错误
1258    pub fn bulkhead_full(max_concurrent: usize) -> Self {
1259        Self::new(WaeErrorKind::BulkheadFull { max_concurrent })
1260    }
1261
1262    // ========== 调度器错误便捷方法 ==========
1263
1264    /// 创建任务未找到错误
1265    pub fn task_not_found(task_id: impl Into<String>) -> Self {
1266        Self::new(WaeErrorKind::TaskNotFound { task_id: task_id.into() })
1267    }
1268
1269    /// 创建无效 Cron 表达式错误
1270    pub fn invalid_cron_expression(expression: impl Into<String>) -> Self {
1271        Self::new(WaeErrorKind::InvalidCronExpression { expression: expression.into() })
1272    }
1273
1274    /// 创建任务执行失败错误
1275    pub fn task_execution_failed(task_id: impl Into<String>, reason: impl Into<String>) -> Self {
1276        Self::new(WaeErrorKind::TaskExecutionFailed { task_id: task_id.into(), reason: reason.into() })
1277    }
1278
1279    /// 创建调度器已关闭错误
1280    pub fn scheduler_shutdown() -> Self {
1281        Self::new(WaeErrorKind::SchedulerShutdown)
1282    }
1283
1284    // ========== 超时错误便捷方法 ==========
1285
1286    /// 创建操作超时错误
1287    pub fn operation_timeout(operation: impl Into<String>, timeout_ms: u64) -> Self {
1288        Self::new(WaeErrorKind::OperationTimeout { operation: operation.into(), timeout_ms })
1289    }
1290
1291    // ========== 配置错误便捷方法 ==========
1292
1293    /// 创建配置缺失错误
1294    pub fn config_missing(key: impl Into<String>) -> Self {
1295        Self::new(WaeErrorKind::ConfigMissing { key: key.into() })
1296    }
1297
1298    /// 创建配置无效错误
1299    pub fn config_invalid(key: impl Into<String>, reason: impl Into<String>) -> Self {
1300        Self::new(WaeErrorKind::ConfigInvalid { key: key.into(), reason: reason.into() })
1301    }
1302
1303    // ========== 内部错误便捷方法 ==========
1304
1305    /// 创建内部错误
1306    pub fn internal(reason: impl Into<String>) -> Self {
1307        Self::new(WaeErrorKind::InternalError { reason: reason.into() })
1308    }
1309
1310    /// 创建未实现错误
1311    pub fn not_implemented(feature: impl Into<String>) -> Self {
1312        Self::new(WaeErrorKind::NotImplemented { feature: feature.into() })
1313    }
1314
1315    /// 创建 IO 错误
1316    pub fn io_error(operation: impl Into<String>, reason: impl Into<String>) -> Self {
1317        Self::new(WaeErrorKind::IoError { operation: operation.into(), reason: reason.into() })
1318    }
1319
1320    /// 创建 JSON 错误
1321    pub fn json_error(reason: impl Into<String>) -> Self {
1322        Self::new(WaeErrorKind::JsonError { reason: reason.into() })
1323    }
1324
1325    /// 创建解析错误
1326    pub fn parse_error(type_name: impl Into<String>, reason: impl Into<String>) -> Self {
1327        Self::new(WaeErrorKind::ParseError { type_name: type_name.into(), reason: reason.into() })
1328    }
1329
1330    /// 创建请求错误
1331    pub fn request_error(url: impl Into<String>, reason: impl Into<String>) -> Self {
1332        Self::new(WaeErrorKind::RequestError { url: url.into(), reason: reason.into() })
1333    }
1334}
1335
1336impl fmt::Display for WaeError {
1337    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1338        write!(f, "{:?}: {}", self.kind.category(), self.kind.i18n_key())
1339    }
1340}
1341
1342impl std::error::Error for WaeError {}
1343
1344impl From<std::io::Error> for WaeError {
1345    fn from(err: std::io::Error) -> Self {
1346        Self::io_error("unknown", err.to_string())
1347    }
1348}
1349
1350impl From<serde_json::Error> for WaeError {
1351    fn from(err: serde_json::Error) -> Self {
1352        Self::json_error(err.to_string())
1353    }
1354}