yufmath/api/
error.rs

1//! # 顶层错误定义
2//!
3//! 定义 Yufmath 库的顶层错误类型,整合各个模块的错误。
4
5use thiserror::Error;
6use crate::parser::ParseError;
7use crate::engine::{ComputeError, ErrorSeverity};
8
9/// 顶层错误类型
10#[derive(Debug, Error)]
11pub enum YufmathError {
12    /// 解析错误
13    #[error("解析错误: {0}")]
14    Parse(#[from] ParseError),
15    
16    /// 计算错误
17    #[error("计算错误: {0}")]
18    Compute(#[from] ComputeError),
19    
20    /// 格式化错误
21    #[error("格式化错误: {0}")]
22    Format(#[from] FormatError),
23    
24    /// IO 错误
25    #[error("IO 错误: {0}")]
26    Io(#[from] std::io::Error),
27    
28    /// 配置错误
29    #[error("配置错误: {message}")]
30    Config { message: String },
31    
32    /// 内部错误
33    #[error("内部错误: {message}")]
34    Internal { message: String },
35}
36
37/// 格式化错误
38#[derive(Debug, Error, Clone, PartialEq)]
39pub enum FormatError {
40    /// 不支持的格式
41    #[error("不支持的格式:{format}")]
42    UnsupportedFormat { format: String },
43    
44    /// 格式化失败
45    #[error("格式化失败:{message}")]
46    FormatFailure { message: String },
47}
48
49impl YufmathError {
50    /// 创建配置错误
51    pub fn config(message: impl Into<String>) -> Self {
52        YufmathError::Config {
53            message: message.into(),
54        }
55    }
56    
57    /// 创建内部错误
58    pub fn internal(message: impl Into<String>) -> Self {
59        YufmathError::Internal {
60            message: message.into(),
61        }
62    }
63    
64    /// 获取用户友好的错误消息
65    pub fn user_friendly_message(&self) -> String {
66        match self {
67            YufmathError::Parse(e) => e.user_friendly_message(),
68            YufmathError::Compute(e) => e.user_friendly_message(),
69            YufmathError::Format(e) => match e {
70                FormatError::UnsupportedFormat { format } => {
71                    format!("不支持的输出格式 '{}'。支持的格式:standard, latex, mathml", format)
72                }
73                FormatError::FormatFailure { message } => {
74                    format!("格式化失败:{}。请检查表达式是否过于复杂", message)
75                }
76            },
77            YufmathError::Io(e) => {
78                format!("文件操作错误:{}。请检查文件路径和权限", e)
79            }
80            YufmathError::Config { message } => {
81                format!("配置错误:{}。请检查配置文件或参数设置", message)
82            }
83            YufmathError::Internal { message } => {
84                format!("内部错误:{}。这可能是程序缺陷,请报告此问题", message)
85            }
86        }
87    }
88    
89    /// 获取修复建议
90    pub fn suggestions(&self) -> Vec<String> {
91        match self {
92            YufmathError::Parse(e) => e.suggestions(),
93            YufmathError::Compute(e) => e.suggestions(),
94            YufmathError::Format(e) => match e {
95                FormatError::UnsupportedFormat { .. } => {
96                    vec![
97                        "使用支持的格式:standard, latex, mathml".to_string(),
98                        "检查格式名称的拼写是否正确".to_string(),
99                    ]
100                }
101                FormatError::FormatFailure { .. } => {
102                    vec![
103                        "尝试简化表达式".to_string(),
104                        "检查表达式是否包含不支持的元素".to_string(),
105                        "使用不同的输出格式".to_string(),
106                    ]
107                }
108            },
109            YufmathError::Io(_) => {
110                vec![
111                    "检查文件路径是否正确".to_string(),
112                    "确保有足够的文件访问权限".to_string(),
113                    "检查磁盘空间是否充足".to_string(),
114                ]
115            }
116            YufmathError::Config { .. } => {
117                vec![
118                    "检查配置文件的语法是否正确".to_string(),
119                    "确保所有必需的配置项都已设置".to_string(),
120                    "参考文档了解正确的配置格式".to_string(),
121                ]
122            }
123            YufmathError::Internal { .. } => {
124                vec![
125                    "这是程序内部错误,请报告给开发者".to_string(),
126                    "尝试重启程序".to_string(),
127                    "检查是否有可用的程序更新".to_string(),
128                ]
129            }
130        }
131    }
132    
133    /// 获取错误的严重程度
134    pub fn severity(&self) -> ErrorSeverity {
135        match self {
136            YufmathError::Parse(_) => ErrorSeverity::Medium,
137            YufmathError::Compute(e) => e.severity(),
138            YufmathError::Format(_) => ErrorSeverity::Low,
139            YufmathError::Io(_) => ErrorSeverity::Medium,
140            YufmathError::Config { .. } => ErrorSeverity::Medium,
141            YufmathError::Internal { .. } => ErrorSeverity::High,
142        }
143    }
144    
145    /// 检查错误是否可以恢复
146    pub fn is_recoverable(&self) -> bool {
147        match self {
148            YufmathError::Parse(_) => true,
149            YufmathError::Compute(e) => e.is_recoverable(),
150            YufmathError::Format(_) => true,
151            YufmathError::Io(_) => true,
152            YufmathError::Config { .. } => true,
153            YufmathError::Internal { .. } => false,
154        }
155    }
156    
157    /// 生成完整的错误报告
158    pub fn format_error_report(&self, input: Option<&str>) -> String {
159        let mut report = String::new();
160        
161        // 错误标题
162        report.push_str(&format!("错误: {}\n", self.user_friendly_message()));
163        
164        // 如果是解析错误且有输入,显示位置信息
165        if let (YufmathError::Parse(parse_error), Some(input_str)) = (self, input) {
166            if let Some(pos) = parse_error.position() {
167                if pos < input_str.len() {
168                    report.push_str(&format!("\n输入:{}\n", input_str));
169                    report.push_str(&format!("位置:{}{}\n", " ".repeat(pos + 3), "^"));
170                }
171            }
172        }
173        
174        // 严重程度指示
175        report.push_str(&format!("\n严重程度:{:?}\n", self.severity()));
176        
177        // 修复建议
178        let suggestions = self.suggestions();
179        if !suggestions.is_empty() {
180            report.push_str("\n建议解决方案:\n");
181            for (i, suggestion) in suggestions.iter().enumerate() {
182                report.push_str(&format!("  {}. {}\n", i + 1, suggestion));
183            }
184        }
185        
186        // 恢复信息
187        if self.is_recoverable() {
188            report.push_str("\n此错误可以修复,请根据建议进行调整后重试\n");
189        } else {
190            report.push_str("\n此错误无法自动恢复,可能需要程序重启或联系技术支持\n");
191        }
192        
193        report
194    }
195}
196
197impl FormatError {
198    /// 创建不支持的格式错误
199    pub fn unsupported_format(format: impl Into<String>) -> Self {
200        FormatError::UnsupportedFormat {
201            format: format.into(),
202        }
203    }
204    
205    /// 创建格式化失败错误
206    pub fn format_failure(message: impl Into<String>) -> Self {
207        FormatError::FormatFailure {
208            message: message.into(),
209        }
210    }
211}