Skip to main content

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}