1use thiserror::Error;
6
7#[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#[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#[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
116impl ActrCliError {
118 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 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 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
190impl 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
245pub struct ErrorReporter;
247
248impl ErrorReporter {
249 pub fn format_error(error: &ActrCliError) -> String {
251 let mut output = Vec::new();
252
253 output.push(error.user_message());
255 output.push(String::new());
256
257 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 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 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 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 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 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 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 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 if report.is_success() {
365 output.push("✨ 总体状态:所有验证通过".to_string());
366 } else {
367 output.push("❌ 总体状态:存在问题需要解决".to_string());
368 }
369
370 output.join("\n")
371 }
372}