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