fob_cli/error/
miette.rs

1//! Miette diagnostic conversion for CLI errors.
2//!
3//! This module provides conversion from CLI errors to miette diagnostics
4//! for beautiful error reporting.
5
6use crate::error::{BuildError, CliError};
7use fob_bundler::diagnostics::to_diagnostic_error;
8use miette::Report;
9
10/// Convert CliError to miette Report
11pub fn cli_error_to_miette(err: CliError) -> Report {
12    match err {
13        CliError::Build(e) => build_error_to_miette(e),
14        CliError::Config(e) => miette::miette!("Configuration error: {}", e),
15        CliError::Core(msg) => {
16            // Try to parse as bundler error
17            miette::miette!("Bundler error: {}", msg)
18        }
19        _ => miette::miette!("{}", err),
20    }
21}
22
23/// Convert BuildError to miette Report
24pub fn build_error_to_miette(err: BuildError) -> Report {
25    match err {
26        BuildError::ResolutionFailed {
27            module,
28            importer,
29            hint,
30        } => {
31            miette::miette!(
32                "Failed to resolve module: {}\nImported from: {}\n\nHint: {}",
33                module,
34                importer.display(),
35                hint
36            )
37        }
38        BuildError::CircularDependency { cycle } => {
39            miette::miette!(
40                "Circular dependency detected:\n{}\n\nHint: Refactor to remove circular imports",
41                cycle
42            )
43        }
44        BuildError::TransformError { file, error, hint } => {
45            miette::miette!(
46                "Transform error in {}: {}\n\nHint: {}",
47                file.display(),
48                error,
49                hint
50            )
51        }
52        _ => miette::miette!("{}", err),
53    }
54}
55
56/// Convert fob-bundler Error to miette Report
57pub fn bundler_error_to_miette(err: fob_bundler::Error) -> Report {
58    match err {
59        fob_bundler::Error::Bundler(diagnostics) => {
60            if diagnostics.is_empty() {
61                miette::miette!("Unknown bundler error")
62            } else if diagnostics.len() == 1 {
63                // Convert single diagnostic to miette
64                let diag_error = to_diagnostic_error(diagnostics.into_iter().next().unwrap());
65                miette::Report::new(diag_error)
66            } else {
67                // Multiple diagnostics - use the first one as primary
68                let primary_diag = diagnostics.first().unwrap();
69                let diag_error = to_diagnostic_error(primary_diag.clone());
70                miette::Report::new(diag_error)
71            }
72        }
73        _ => {
74            // Use the Diagnostic implementation we added to Error
75            miette::Report::new(err)
76        }
77    }
78}