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