1use colored::*;
4
5pub fn print_error(context: &str, error: &anyhow::Error) {
7 eprintln!("{} {}", "Error:".red().bold(), context);
8 eprintln!(" {}", error.to_string().red());
9
10 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
18pub 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
24pub 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 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 let error = anyhow!("simple error message");
43
44 print_error("operation failed", &error);
46 }
47
48 #[test]
49 fn test_print_error_with_chain() {
50 let error = create_error_chain();
52
53 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 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 print_error_with_suggestion("operation failed", &error, suggestion);
73 }
74
75 #[test]
76 fn test_print_warning() {
77 print_warning("this is a warning message");
79 }
80
81 #[test]
82 fn test_print_warning_empty() {
83 print_warning("");
85 }
86
87 #[test]
88 fn test_print_warning_special_chars() {
89 print_warning("warning: path/to/file contains special chars: @#$%");
91 }
92}