actr_cli/core/
error.rs

1//! 统一错误处理
2//!
3//! 定义了CLI工具的统一错误类型和处理策略
4
5use thiserror::Error;
6
7/// CLI 统一错误类型
8#[derive(Debug, Error)]
9pub enum ActrCliError {
10    #[error("配置错误: {message}")]
11    Config { message: String },
12
13    #[error("无效项目: {message}")]
14    InvalidProject { message: String },
15
16    #[error("网络错误: {message}")]
17    Network { message: String },
18
19    #[error("依赖错误: {message}")]
20    Dependency { message: String },
21
22    #[error("服务发现错误: {message}")]
23    ServiceDiscovery { message: String },
24
25    #[error("指纹验证错误: {message}")]
26    FingerprintValidation { message: String },
27
28    #[error("代码生成错误: {message}")]
29    CodeGeneration { message: String },
30
31    #[error("缓存错误: {message}")]
32    Cache { message: String },
33
34    #[error("用户交互错误: {message}")]
35    UserInterface { message: String },
36
37    #[error("命令执行错误: {message}")]
38    Command { message: String },
39
40    #[error("验证失败: {details}")]
41    ValidationFailed { details: String },
42
43    #[error("安装失败: {reason}")]
44    InstallFailed { reason: String },
45
46    #[error("组件未注册: {component}")]
47    ComponentNotRegistered { component: String },
48
49    #[error("IO 错误")]
50    Io(#[from] std::io::Error),
51
52    #[error("序列化错误")]
53    Serialization(#[from] toml::de::Error),
54
55    #[error("HTTP 错误")]
56    Http(#[from] reqwest::Error),
57
58    #[error("其他错误: {0}")]
59    Other(#[from] anyhow::Error),
60}
61
62/// 安装错误
63#[derive(Debug, Error)]
64pub enum InstallError {
65    #[error("依赖解析失败: {dependency}")]
66    DependencyResolutionFailed { dependency: String },
67
68    #[error("服务不可用: {service}")]
69    ServiceUnavailable { service: String },
70
71    #[error("网络连接失败: {uri}")]
72    NetworkConnectionFailed { uri: String },
73
74    #[error("指纹验证失败: {service} - 期望: {expected}, 实际: {actual}")]
75    FingerprintMismatch {
76        service: String,
77        expected: String,
78        actual: String,
79    },
80
81    #[error("版本冲突: {details}")]
82    VersionConflict { details: String },
83
84    #[error("缓存操作失败: {operation}")]
85    CacheOperationFailed { operation: String },
86
87    #[error("配置更新失败: {reason}")]
88    ConfigUpdateFailed { reason: String },
89
90    #[error("前置验证失败: {failures:?}")]
91    PreCheckFailed { failures: Vec<String> },
92}
93
94/// 验证错误
95#[derive(Debug, Error)]
96pub enum ValidationError {
97    #[error("配置文件语法错误: {file}")]
98    ConfigSyntaxError { file: String },
99
100    #[error("依赖不存在: {dependency}")]
101    DependencyNotFound { dependency: String },
102
103    #[error("网络不可达: {uri}")]
104    NetworkUnreachable { uri: String },
105
106    #[error("指纹不匹配: {service}")]
107    FingerprintMismatch { service: String },
108
109    #[error("循环依赖: {cycle}")]
110    CircularDependency { cycle: String },
111
112    #[error("权限不足: {resource}")]
113    InsufficientPermissions { resource: String },
114}
115
116/// 用户友好的错误显示
117impl ActrCliError {
118    /// 获取用户友好的错误消息
119    pub fn user_message(&self) -> String {
120        match self {
121            ActrCliError::Config { message } => {
122                format!("⚠️  配置文件错误:{message}\n💡 提示:请检查 Actr.toml 文件的语法和内容")
123            }
124            ActrCliError::Network { message } => {
125                format!("🌐 网络连接错误:{message}\n💡 提示:请检查网络连接和服务地址")
126            }
127            ActrCliError::Dependency { message } => {
128                format!("📦 依赖错误:{message}\n💡 提示:运行 'actr check' 检查依赖状态")
129            }
130            ActrCliError::ValidationFailed { details } => {
131                format!("❌ 验证失败:{details}\n💡 提示:请解决上述问题后重试")
132            }
133            ActrCliError::InstallFailed { reason } => {
134                format!("📥 安装失败:{reason}\n💡 提示:运行 'actr check' 检查环境状态")
135            }
136            _ => self.to_string(),
137        }
138    }
139
140    /// 获取可能的解决方案
141    pub fn suggested_actions(&self) -> Vec<String> {
142        match self {
143            ActrCliError::Config { .. } => vec![
144                "检查 Actr.toml 文件语法".to_string(),
145                "运行 'actr config test' 验证配置".to_string(),
146                "参考文档中的配置示例".to_string(),
147            ],
148            ActrCliError::Network { .. } => vec![
149                "检查网络连接".to_string(),
150                "确认服务地址正确".to_string(),
151                "检查防火墙设置".to_string(),
152                "运行 'actr check --verbose' 获取详细信息".to_string(),
153            ],
154            ActrCliError::Dependency { .. } => vec![
155                "运行 'actr check' 检查依赖状态".to_string(),
156                "运行 'actr install' 安装缺失的依赖".to_string(),
157                "运行 'actr discovery' 查找可用服务".to_string(),
158            ],
159            ActrCliError::ValidationFailed { .. } => vec![
160                "检查并修复报告中的问题".to_string(),
161                "运行 'actr check --verbose' 获取详细诊断".to_string(),
162                "确保所有依赖服务可用".to_string(),
163            ],
164            ActrCliError::InstallFailed { .. } => vec![
165                "检查磁盘空间".to_string(),
166                "检查网络连接".to_string(),
167                "运行 'actr check' 验证环境".to_string(),
168                "尝试清理缓存后重试".to_string(),
169            ],
170            _ => vec!["查看详细错误信息".to_string()],
171        }
172    }
173
174    /// 获取相关文档链接
175    pub fn documentation_links(&self) -> Vec<(&str, &str)> {
176        match self {
177            ActrCliError::Config { .. } => vec![
178                ("配置文档", "https://docs.actor-rtc.com/config"),
179                ("Actr.toml 参考", "https://docs.actor-rtc.com/actr-toml"),
180            ],
181            ActrCliError::Dependency { .. } => vec![
182                ("依赖管理", "https://docs.actor-rtc.com/dependencies"),
183                ("故障排除", "https://docs.actor-rtc.com/troubleshooting"),
184            ],
185            _ => vec![("用户指南", "https://docs.actor-rtc.com/guide")],
186        }
187    }
188}
189
190/// 将验证报告转换为错误
191impl From<super::components::ValidationReport> for ActrCliError {
192    fn from(report: super::components::ValidationReport) -> Self {
193        let mut details = Vec::new();
194
195        if !report.config_validation.is_valid {
196            details.extend(
197                report
198                    .config_validation
199                    .errors
200                    .iter()
201                    .map(|e| format!("配置错误: {e}")),
202            );
203        }
204
205        for dep in &report.dependency_validation {
206            if !dep.is_available {
207                details.push(format!(
208                    "依赖不可用: {} - {}",
209                    dep.dependency,
210                    dep.error.as_deref().unwrap_or("未知错误")
211                ));
212            }
213        }
214
215        for net in &report.network_validation {
216            if !net.is_reachable {
217                details.push(format!(
218                    "网络不可达: {} - {}",
219                    net.uri,
220                    net.error.as_deref().unwrap_or("连接失败")
221                ));
222            }
223        }
224
225        for fp in &report.fingerprint_validation {
226            if !fp.is_valid {
227                details.push(format!(
228                    "指纹验证失败: {} - {}",
229                    fp.dependency,
230                    fp.error.as_deref().unwrap_or("指纹不匹配")
231                ));
232            }
233        }
234
235        for conflict in &report.conflicts {
236            details.push(format!("依赖冲突: {}", conflict.description));
237        }
238
239        ActrCliError::ValidationFailed {
240            details: details.join("; "),
241        }
242    }
243}
244
245/// 错误报告格式化器
246pub struct ErrorReporter;
247
248impl ErrorReporter {
249    /// 格式化错误报告
250    pub fn format_error(error: &ActrCliError) -> String {
251        let mut output = Vec::new();
252
253        // 主要错误信息
254        output.push(error.user_message());
255        output.push(String::new());
256
257        // 建议的解决方案
258        let actions = error.suggested_actions();
259        if !actions.is_empty() {
260            output.push("🔧 建议的解决方案:".to_string());
261            for (i, action) in actions.iter().enumerate() {
262                output.push(format!("   {}. {}", i + 1, action));
263            }
264            output.push(String::new());
265        }
266
267        // 文档链接
268        let docs = error.documentation_links();
269        if !docs.is_empty() {
270            output.push("📚 相关文档:".to_string());
271            for (title, url) in docs {
272                output.push(format!("   • {title}: {url}"));
273            }
274            output.push(String::new());
275        }
276
277        output.join("\n")
278    }
279
280    /// 格式化验证报告
281    pub fn format_validation_report(report: &super::components::ValidationReport) -> String {
282        let mut output = vec![
283            "🔍 依赖验证报告".to_string(),
284            "=".repeat(50),
285            String::new(),
286            "📋 配置文件验证:".to_string(),
287        ];
288
289        // 配置验证
290        if report.config_validation.is_valid {
291            output.push("   ✅ 通过".to_string());
292        } else {
293            output.push("   ❌ 失败".to_string());
294            for error in &report.config_validation.errors {
295                output.push(format!("      • {error}"));
296            }
297        }
298        output.push(String::new());
299
300        // 依赖验证
301        output.push("📦 依赖可用性验证:".to_string());
302        for dep in &report.dependency_validation {
303            if dep.is_available {
304                output.push(format!("   ✅ {} - 可用", dep.dependency));
305            } else {
306                output.push(format!(
307                    "   ❌ {} - {}",
308                    dep.dependency,
309                    dep.error.as_deref().unwrap_or("不可用")
310                ));
311            }
312        }
313        output.push(String::new());
314
315        // 网络验证
316        output.push("🌐 网络连通性验证:".to_string());
317        for net in &report.network_validation {
318            if net.is_reachable {
319                let latency = net
320                    .latency_ms
321                    .map(|ms| format!(" ({ms}ms)"))
322                    .unwrap_or_default();
323                output.push(format!("   ✅ {}{}", net.uri, latency));
324            } else {
325                output.push(format!(
326                    "   ❌ {} - {}",
327                    net.uri,
328                    net.error.as_deref().unwrap_or("不可达")
329                ));
330            }
331        }
332        output.push(String::new());
333
334        // 指纹验证
335        if !report.fingerprint_validation.is_empty() {
336            output.push("🔐 指纹验证:".to_string());
337            for fp in &report.fingerprint_validation {
338                if fp.is_valid {
339                    output.push(format!("   ✅ {} - 验证通过", fp.dependency));
340                } else {
341                    output.push(format!(
342                        "   ❌ {} - {}",
343                        fp.dependency,
344                        fp.error.as_deref().unwrap_or("验证失败")
345                    ));
346                }
347            }
348            output.push(String::new());
349        }
350
351        // 冲突报告
352        if !report.conflicts.is_empty() {
353            output.push("⚠️ 依赖冲突:".to_string());
354            for conflict in &report.conflicts {
355                output.push(format!(
356                    "   • {} vs {}: {}",
357                    conflict.dependency_a, conflict.dependency_b, conflict.description
358                ));
359            }
360            output.push(String::new());
361        }
362
363        // 总结
364        if report.is_success() {
365            output.push("✨ 总体状态:所有验证通过".to_string());
366        } else {
367            output.push("❌ 总体状态:存在问题需要解决".to_string());
368        }
369
370        output.join("\n")
371    }
372}