prodigy/app/error_handling.rs
1//! Error handling utilities
2//!
3//! This module provides centralized error handling for the application.
4
5use tracing::error;
6
7/// Handle fatal errors and exit with appropriate status code
8///
9/// This function processes errors and displays them according to their type:
10/// - For `ProdigyError`: Shows user message always, developer message in verbose mode
11/// - For other errors: Shows error message and attempts to determine exit code
12///
13/// # Verbose Mode Behavior
14/// - `verbose = 0`: User-friendly messages only
15/// - `verbose >= 1`: Includes full developer context with error chain
16pub fn handle_fatal_error(error: anyhow::Error, verbose: u8) -> ! {
17 use crate::error::ProdigyError;
18
19 error!("Fatal error: {}", error);
20
21 // Check if it's a ProdigyError for better handling
22 let exit_code = if let Some(prodigy_err) = error.downcast_ref::<ProdigyError>() {
23 // Use the user-friendly message for ProdigyError
24 eprintln!("{}", prodigy_err.user_message());
25
26 // Show developer message with full context chain in verbose mode
27 if verbose >= 1 {
28 eprintln!("\nContext Chain:\n{}", prodigy_err.developer_message());
29 }
30
31 prodigy_err.exit_code()
32 } else {
33 // Fallback for non-ProdigyError errors
34 eprintln!("Error: {error}");
35
36 // Show chain in verbose mode for non-ProdigyError errors
37 if verbose >= 1 {
38 eprintln!("\nError chain:");
39 for (i, cause) in error.chain().enumerate() {
40 eprintln!(" {}: {}", i, cause);
41 }
42 }
43
44 // Try to determine exit code based on error message
45 if error.to_string().contains("No workflow ID provided")
46 || error.to_string().contains("required")
47 || error.to_string().contains("Please specify")
48 {
49 2 // ARGUMENT_ERROR
50 } else {
51 1 // GENERAL_ERROR
52 }
53 };
54
55 std::process::exit(exit_code)
56}