mf_core/
error.rs

1use thiserror::Error;
2
3/// 统一的 Forge 错误类型
4///
5/// 这个枚举定义了 ModuForge 核心模块中可能出现的所有错误类型,
6/// 提供了结构化的错误处理和更好的错误分类。
7#[derive(Error, Debug)]
8pub enum ForgeError {
9    /// 状态管理相关错误
10    #[error("状态错误: {message}")]
11    State {
12        message: String,
13        #[source]
14        source: Option<Box<dyn std::error::Error + Send + Sync>>,
15    },
16
17    /// 事件系统相关错误
18    #[error("事件错误: {message}")]
19    Event {
20        message: String,
21        #[source]
22        source: Option<Box<dyn std::error::Error + Send + Sync>>,
23    },
24
25    /// 中间件相关错误
26    #[error("中间件错误: {message}")]
27    Middleware {
28        message: String,
29        middleware_name: Option<String>,
30        #[source]
31        source: Option<Box<dyn std::error::Error + Send + Sync>>,
32    },
33
34    /// 扩展和插件相关错误
35    #[error("扩展错误: {message}")]
36    Extension {
37        message: String,
38        extension_name: Option<String>,
39        #[source]
40        source: Option<Box<dyn std::error::Error + Send + Sync>>,
41    },
42
43    /// 事务处理相关错误
44    #[error("事务错误: {message}")]
45    Transaction {
46        message: String,
47        transaction_id: Option<u64>,
48        #[source]
49        source: Option<Box<dyn std::error::Error + Send + Sync>>,
50    },
51
52    /// 历史记录相关错误
53    #[error("历史记录错误: {message}")]
54    History {
55        message: String,
56        #[source]
57        source: Option<Box<dyn std::error::Error + Send + Sync>>,
58    },
59
60    /// 配置相关错误
61    #[error("配置错误: {message}")]
62    Config {
63        message: String,
64        config_key: Option<String>,
65        #[source]
66        source: Option<Box<dyn std::error::Error + Send + Sync>>,
67    },
68
69    /// 存储相关错误
70    #[error("存储错误: {message}")]
71    Storage {
72        message: String,
73        #[source]
74        source: Option<Box<dyn std::error::Error + Send + Sync>>,
75    },
76
77    /// 缓存相关错误
78    #[error("缓存错误: {message}")]
79    Cache {
80        message: String,
81        #[source]
82        source: Option<Box<dyn std::error::Error + Send + Sync>>,
83    },
84
85    /// 引擎相关错误
86    #[error("引擎错误: {message}")]
87    Engine {
88        message: String,
89        #[source]
90        source: Option<Box<dyn std::error::Error + Send + Sync>>,
91    },
92
93    /// 超时错误
94    #[error("操作超时: {operation} (超时时间: {timeout_ms}ms)")]
95    Timeout {
96        operation: String,
97        timeout_ms: u64,
98    },
99
100    /// 资源不足错误
101    #[error("资源不足: {resource_type}")]
102    ResourceExhausted {
103        resource_type: String,
104        current_usage: Option<usize>,
105        limit: Option<usize>,
106    },
107
108    /// 并发错误
109    #[error("并发错误: {message}")]
110    Concurrency {
111        message: String,
112        #[source]
113        source: Option<Box<dyn std::error::Error + Send + Sync>>,
114    },
115
116    /// 验证错误
117    #[error("验证失败: {message}")]
118    Validation {
119        message: String,
120        field: Option<String>,
121    },
122
123    /// 外部依赖错误
124    #[error("外部依赖错误: {dependency}")]
125    ExternalDependency {
126        dependency: String,
127        #[source]
128        source: Box<dyn std::error::Error + Send + Sync>,
129    },
130
131    /// 内部错误(不应该发生的错误)
132    #[error("内部错误: {message}")]
133    Internal {
134        message: String,
135        location: Option<String>,
136    },
137
138    /// 兼容性错误,用于包装其他错误类型
139    #[error("其他错误: {0}")]
140    Other(#[from] anyhow::Error),
141}
142
143/// 错误结果类型别名
144pub type ForgeResult<T> = Result<T, ForgeError>;
145
146impl ForgeError {
147    /// 获取错误代码,用于程序化处理
148    pub fn error_code(&self) -> &'static str {
149        match self {
150            ForgeError::State { .. } => "STATE_ERROR",
151            ForgeError::Event { .. } => "EVENT_ERROR",
152            ForgeError::Middleware { .. } => "MIDDLEWARE_ERROR",
153            ForgeError::Extension { .. } => "EXTENSION_ERROR",
154            ForgeError::Transaction { .. } => "TRANSACTION_ERROR",
155            ForgeError::History { .. } => "HISTORY_ERROR",
156            ForgeError::Config { .. } => "CONFIG_ERROR",
157            ForgeError::Storage { .. } => "STORAGE_ERROR",
158            ForgeError::Cache { .. } => "CACHE_ERROR",
159            ForgeError::Engine { .. } => "ENGINE_ERROR",
160            ForgeError::Timeout { .. } => "TIMEOUT_ERROR",
161            ForgeError::ResourceExhausted { .. } => "RESOURCE_EXHAUSTED",
162            ForgeError::Concurrency { .. } => "CONCURRENCY_ERROR",
163            ForgeError::Validation { .. } => "VALIDATION_ERROR",
164            ForgeError::ExternalDependency { .. } => "EXTERNAL_DEPENDENCY_ERROR",
165            ForgeError::Internal { .. } => "INTERNAL_ERROR",
166            ForgeError::Other(_) => "OTHER_ERROR",
167        }
168    }
169
170    /// 检查错误是否可重试
171    pub fn is_retryable(&self) -> bool {
172        matches!(
173            self,
174            ForgeError::Timeout { .. }
175                | ForgeError::ResourceExhausted { .. }
176                | ForgeError::Concurrency { .. }
177                | ForgeError::ExternalDependency { .. }
178        )
179    }
180
181    /// 检查错误是否为临时性错误
182    pub fn is_temporary(&self) -> bool {
183        matches!(
184            self,
185            ForgeError::Timeout { .. }
186                | ForgeError::ResourceExhausted { .. }
187                | ForgeError::Concurrency { .. }
188        )
189    }
190}
191
192/// 错误构造工具函数
193///
194/// 这些函数提供了便捷的方式来创建各种类型的错误,
195/// 同时保持与现有代码的向后兼容性。
196pub mod error_utils {
197    use super::*;
198
199    /// 将任意错误转换为 ForgeError
200    pub fn map_error<T, E: std::error::Error + Send + Sync + 'static>(
201        result: Result<T, E>,
202        context: &str,
203    ) -> ForgeResult<T> {
204        result.map_err(|e| ForgeError::Other(anyhow::anyhow!("{}: {}", context, e)))
205    }
206
207    /// 创建状态错误
208    pub fn state_error(msg: impl Into<String>) -> ForgeError {
209        ForgeError::State {
210            message: msg.into(),
211            source: None,
212        }
213    }
214
215    /// 创建带源错误的状态错误
216    pub fn state_error_with_source(
217        msg: impl Into<String>,
218        source: impl std::error::Error + Send + Sync + 'static,
219    ) -> ForgeError {
220        ForgeError::State {
221            message: msg.into(),
222            source: Some(Box::new(source)),
223        }
224    }
225
226    /// 创建事件错误
227    pub fn event_error(msg: impl Into<String>) -> ForgeError {
228        ForgeError::Event {
229            message: msg.into(),
230            source: None,
231        }
232    }
233
234    /// 创建带源错误的事件错误
235    pub fn event_error_with_source(
236        msg: impl Into<String>,
237        source: impl std::error::Error + Send + Sync + 'static,
238    ) -> ForgeError {
239        ForgeError::Event {
240            message: msg.into(),
241            source: Some(Box::new(source)),
242        }
243    }
244
245    /// 创建中间件错误
246    pub fn middleware_error(msg: impl Into<String>) -> ForgeError {
247        ForgeError::Middleware {
248            message: msg.into(),
249            middleware_name: None,
250            source: None,
251        }
252    }
253
254    /// 创建带中间件名称的中间件错误
255    pub fn middleware_error_with_name(
256        msg: impl Into<String>,
257        middleware_name: impl Into<String>,
258    ) -> ForgeError {
259        ForgeError::Middleware {
260            message: msg.into(),
261            middleware_name: Some(middleware_name.into()),
262            source: None,
263        }
264    }
265
266    /// 创建带源错误的中间件错误
267    pub fn middleware_error_with_source(
268        msg: impl Into<String>,
269        middleware_name: Option<String>,
270        source: impl std::error::Error + Send + Sync + 'static,
271    ) -> ForgeError {
272        ForgeError::Middleware {
273            message: msg.into(),
274            middleware_name,
275            source: Some(Box::new(source)),
276        }
277    }
278
279    /// 创建扩展错误
280    pub fn extension_error(msg: impl Into<String>) -> ForgeError {
281        ForgeError::Extension {
282            message: msg.into(),
283            extension_name: None,
284            source: None,
285        }
286    }
287
288    /// 创建带扩展名称的扩展错误
289    pub fn extension_error_with_name(
290        msg: impl Into<String>,
291        extension_name: impl Into<String>,
292    ) -> ForgeError {
293        ForgeError::Extension {
294            message: msg.into(),
295            extension_name: Some(extension_name.into()),
296            source: None,
297        }
298    }
299
300    /// 创建插件错误(扩展错误的别名,保持向后兼容)
301    pub fn plugin_error(msg: impl Into<String>) -> ForgeError {
302        extension_error(msg)
303    }
304
305    /// 创建事务错误
306    pub fn transaction_error(msg: impl Into<String>) -> ForgeError {
307        ForgeError::Transaction {
308            message: msg.into(),
309            transaction_id: None,
310            source: None,
311        }
312    }
313
314    /// 创建带事务ID的事务错误
315    pub fn transaction_error_with_id(
316        msg: impl Into<String>,
317        transaction_id: u64,
318    ) -> ForgeError {
319        ForgeError::Transaction {
320            message: msg.into(),
321            transaction_id: Some(transaction_id),
322            source: None,
323        }
324    }
325
326    /// 创建历史记录错误
327    pub fn history_error(msg: impl Into<String>) -> ForgeError {
328        ForgeError::History {
329            message: msg.into(),
330            source: None,
331        }
332    }
333
334    /// 创建配置错误
335    pub fn config_error(msg: impl Into<String>) -> ForgeError {
336        ForgeError::Config {
337            message: msg.into(),
338            config_key: None,
339            source: None,
340        }
341    }
342
343    /// 创建带配置键的配置错误
344    pub fn config_error_with_key(
345        msg: impl Into<String>,
346        config_key: impl Into<String>,
347    ) -> ForgeError {
348        ForgeError::Config {
349            message: msg.into(),
350            config_key: Some(config_key.into()),
351            source: None,
352        }
353    }
354
355    /// 创建存储错误
356    pub fn storage_error(msg: impl Into<String>) -> ForgeError {
357        ForgeError::Storage {
358            message: msg.into(),
359            source: None,
360        }
361    }
362
363    /// 创建缓存错误
364    pub fn cache_error(msg: impl Into<String>) -> ForgeError {
365        ForgeError::Cache {
366            message: msg.into(),
367            source: None,
368        }
369    }
370
371    /// 创建引擎错误
372    pub fn engine_error(msg: impl Into<String>) -> ForgeError {
373        ForgeError::Engine {
374            message: msg.into(),
375            source: None,
376        }
377    }
378
379    /// 创建超时错误
380    pub fn timeout_error(operation: impl Into<String>) -> ForgeError {
381        ForgeError::Timeout {
382            operation: operation.into(),
383            timeout_ms: 0, // 默认值,可以根据需要调整
384        }
385    }
386
387    /// 创建带超时时间的超时错误
388    pub fn timeout_error_with_duration(operation: impl Into<String>, timeout_ms: u64) -> ForgeError {
389        ForgeError::Timeout {
390            operation: operation.into(),
391            timeout_ms,
392        }
393    }
394
395    /// 创建运行时错误
396    pub fn runtime_error(msg: impl Into<String>) -> ForgeError {
397        ForgeError::Engine {
398            message: msg.into(),
399            source: None,
400        }
401    }
402
403    /// 创建资源不足错误
404    pub fn resource_exhausted_error(resource_type: impl Into<String>) -> ForgeError {
405        ForgeError::ResourceExhausted {
406            resource_type: resource_type.into(),
407            current_usage: None,
408            limit: None,
409        }
410    }
411
412    /// 创建带使用量信息的资源不足错误
413    pub fn resource_exhausted_error_with_usage(
414        resource_type: impl Into<String>,
415        current_usage: usize,
416        limit: usize,
417    ) -> ForgeError {
418        ForgeError::ResourceExhausted {
419            resource_type: resource_type.into(),
420            current_usage: Some(current_usage),
421            limit: Some(limit),
422        }
423    }
424
425    /// 创建并发错误
426    pub fn concurrency_error(msg: impl Into<String>) -> ForgeError {
427        ForgeError::Concurrency {
428            message: msg.into(),
429            source: None,
430        }
431    }
432
433    /// 创建验证错误
434    pub fn validation_error(msg: impl Into<String>) -> ForgeError {
435        ForgeError::Validation {
436            message: msg.into(),
437            field: None,
438        }
439    }
440
441    /// 创建带字段信息的验证错误
442    pub fn validation_error_with_field(
443        msg: impl Into<String>,
444        field: impl Into<String>,
445    ) -> ForgeError {
446        ForgeError::Validation {
447            message: msg.into(),
448            field: Some(field.into()),
449        }
450    }
451
452    /// 创建外部依赖错误
453    pub fn external_dependency_error(
454        dependency: impl Into<String>,
455        source: impl std::error::Error + Send + Sync + 'static,
456    ) -> ForgeError {
457        ForgeError::ExternalDependency {
458            dependency: dependency.into(),
459            source: Box::new(source),
460        }
461    }
462
463    /// 创建内部错误
464    pub fn internal_error(msg: impl Into<String>) -> ForgeError {
465        ForgeError::Internal {
466            message: msg.into(),
467            location: None,
468        }
469    }
470
471    /// 创建带位置信息的内部错误
472    pub fn internal_error_with_location(
473        msg: impl Into<String>,
474        location: impl Into<String>,
475    ) -> ForgeError {
476        ForgeError::Internal {
477            message: msg.into(),
478            location: Some(location.into()),
479        }
480    }
481}
482
483// 错误转换实现
484impl From<crate::config::ConfigValidationError> for ForgeError {
485    fn from(err: crate::config::ConfigValidationError) -> Self {
486        ForgeError::Validation {
487            field: Some("config".to_string()),
488            message: err.to_string(),
489        }
490    }
491}