Skip to main content

probador/
error.rs

1//! Error types for the CLI
2
3use thiserror::Error;
4
5/// Result type for CLI operations
6pub type CliResult<T> = Result<T, CliError>;
7
8/// Errors that can occur in the CLI
9#[derive(Debug, Error)]
10pub enum CliError {
11    /// Configuration error
12    #[error("Configuration error: {message}")]
13    Config {
14        /// Error message
15        message: String,
16    },
17
18    /// Test execution error
19    #[error("Test execution failed: {message}")]
20    TestExecution {
21        /// Error message
22        message: String,
23    },
24
25    /// IO error
26    #[error("I/O error: {0}")]
27    Io(#[from] std::io::Error),
28
29    /// Probar library error
30    #[error("Probar error: {0}")]
31    Probar(#[from] jugar_probar::ProbarError),
32
33    /// Invalid argument
34    #[error("Invalid argument: {message}")]
35    InvalidArgument {
36        /// Error message
37        message: String,
38    },
39
40    /// Report generation error
41    #[error("Report generation failed: {message}")]
42    ReportGeneration {
43        /// Error message
44        message: String,
45    },
46
47    /// Recording error
48    #[error("Recording failed: {message}")]
49    Recording {
50        /// Error message
51        message: String,
52    },
53
54    /// Generic error for extensible error handling
55    #[error("{0}")]
56    Generic(String),
57}
58
59impl CliError {
60    /// Create a configuration error
61    #[must_use]
62    pub fn config(message: impl Into<String>) -> Self {
63        Self::Config {
64            message: message.into(),
65        }
66    }
67
68    /// Create a test execution error
69    #[must_use]
70    pub fn test_execution(message: impl Into<String>) -> Self {
71        Self::TestExecution {
72            message: message.into(),
73        }
74    }
75
76    /// Create an invalid argument error
77    #[must_use]
78    pub fn invalid_argument(message: impl Into<String>) -> Self {
79        Self::InvalidArgument {
80            message: message.into(),
81        }
82    }
83
84    /// Create a report generation error
85    #[must_use]
86    pub fn report_generation(message: impl Into<String>) -> Self {
87        Self::ReportGeneration {
88            message: message.into(),
89        }
90    }
91
92    /// Create a recording error
93    #[must_use]
94    pub fn recording(message: impl Into<String>) -> Self {
95        Self::Recording {
96            message: message.into(),
97        }
98    }
99}
100
101#[cfg(test)]
102#[allow(clippy::unwrap_used, clippy::expect_used)]
103mod tests {
104    use super::*;
105
106    #[test]
107    fn test_config_error() {
108        let err = CliError::config("bad config");
109        assert!(err.to_string().contains("Configuration"));
110        assert!(err.to_string().contains("bad config"));
111    }
112
113    #[test]
114    fn test_test_execution_error() {
115        let err = CliError::test_execution("test failed");
116        assert!(err.to_string().contains("Test execution"));
117    }
118
119    #[test]
120    fn test_invalid_argument_error() {
121        let err = CliError::invalid_argument("bad arg");
122        assert!(err.to_string().contains("Invalid argument"));
123    }
124
125    #[test]
126    fn test_report_generation_error() {
127        let err = CliError::report_generation("report failed");
128        assert!(err.to_string().contains("Report"));
129    }
130
131    #[test]
132    fn test_recording_error() {
133        let err = CliError::recording("recording failed");
134        assert!(err.to_string().contains("Recording"));
135    }
136
137    #[test]
138    fn test_io_error_from() {
139        let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
140        let cli_err: CliError = io_err.into();
141        assert!(cli_err.to_string().contains("I/O"));
142    }
143}