Skip to main content

design/
errors.rs

1//! Error handling utilities
2
3use colored::*;
4
5/// Print a formatted error message
6pub fn print_error(context: &str, error: &anyhow::Error) {
7    eprintln!("{} {}", "Error:".red().bold(), context);
8    eprintln!("  {}", error.to_string().red());
9
10    // Show chain of causes
11    let mut current = error.source();
12    while let Some(cause) = current {
13        eprintln!("  {} {}", "Caused by:".dimmed(), cause.to_string().dimmed());
14        current = std::error::Error::source(cause);
15    }
16}
17
18/// Print an error with a suggestion
19pub fn print_error_with_suggestion(context: &str, error: &anyhow::Error, suggestion: &str) {
20    print_error(context, error);
21    eprintln!("\n{} {}", "Suggestion:".cyan().bold(), suggestion);
22}
23
24/// Print a warning message
25pub fn print_warning(message: &str) {
26    eprintln!("{} {}", "Warning:".yellow().bold(), message);
27}
28
29#[cfg(test)]
30mod tests {
31    use super::*;
32    use anyhow::anyhow;
33
34    // Helper to create a chain of errors
35    fn create_error_chain() -> anyhow::Error {
36        anyhow!("root cause").context("intermediate error").context("top level error")
37    }
38
39    #[test]
40    fn test_print_error_simple() {
41        // Simple error without chain
42        let error = anyhow!("simple error message");
43
44        // Just verify it doesn't panic - output goes to stderr
45        print_error("operation failed", &error);
46    }
47
48    #[test]
49    fn test_print_error_with_chain() {
50        // Error with chain of causes
51        let error = create_error_chain();
52
53        // Verify it doesn't panic with chained errors
54        print_error("complex operation failed", &error);
55    }
56
57    #[test]
58    fn test_print_error_with_suggestion_simple() {
59        let error = anyhow!("file not found");
60        let suggestion = "Make sure the file exists and you have permission to read it";
61
62        // Verify it doesn't panic
63        print_error_with_suggestion("read operation failed", &error, suggestion);
64    }
65
66    #[test]
67    fn test_print_error_with_suggestion_chain() {
68        let error = create_error_chain();
69        let suggestion = "Try running with --verbose for more details";
70
71        // Verify it doesn't panic with chained errors
72        print_error_with_suggestion("operation failed", &error, suggestion);
73    }
74
75    #[test]
76    fn test_print_warning() {
77        // Simple warning
78        print_warning("this is a warning message");
79    }
80
81    #[test]
82    fn test_print_warning_empty() {
83        // Empty warning
84        print_warning("");
85    }
86
87    #[test]
88    fn test_print_warning_special_chars() {
89        // Warning with special characters
90        print_warning("warning: path/to/file contains special chars: @#$%");
91    }
92}