Skip to main content

apr_qa_runner/
error.rs

1//! Error types for apr-qa-runner
2
3use thiserror::Error;
4
5/// Result type alias
6pub type Result<T> = std::result::Result<T, Error>;
7
8/// Errors that can occur during playbook execution
9#[derive(Debug, Error)]
10pub enum Error {
11    /// Playbook parsing error
12    #[error("Playbook parse error: {0}")]
13    PlaybookParseError(String),
14
15    /// Command execution failed
16    #[error("Command failed: {command} (exit code: {exit_code})")]
17    CommandFailed {
18        /// The command that failed
19        command: String,
20        /// Exit code
21        exit_code: i32,
22        /// Stderr output
23        stderr: String,
24    },
25
26    /// Command timed out
27    #[error("Command timed out after {timeout_ms}ms: {command}")]
28    Timeout {
29        /// The command that timed out
30        command: String,
31        /// Timeout in milliseconds
32        timeout_ms: u64,
33    },
34
35    /// Gateway check failed
36    #[error("Gateway check failed: {gate}")]
37    GatewayFailed {
38        /// The gate that failed
39        gate: String,
40        /// Reason for failure
41        reason: String,
42    },
43
44    /// IO error
45    #[error("IO error: {0}")]
46    IoError(#[from] std::io::Error),
47
48    /// IO error (non-from variant for conversion module)
49    #[error("IO error: {0}")]
50    Io(std::io::Error),
51
52    /// Execution error
53    #[error("Execution error: {0}")]
54    Execution(String),
55
56    /// Execution failed with details
57    #[error("Execution failed: {command} - {reason}")]
58    ExecutionFailed {
59        /// The command that failed
60        command: String,
61        /// Reason for failure
62        reason: String,
63    },
64
65    /// Serialization error
66    #[error("Serialization error: {0}")]
67    SerializationError(#[from] serde_json::Error),
68
69    /// YAML error
70    #[error("YAML error: {0}")]
71    YamlError(#[from] serde_yaml::Error),
72
73    /// Generator error
74    #[error("Generator error: {0}")]
75    GeneratorError(#[from] apr_qa_gen::Error),
76
77    /// Provenance validation error (PMAT-PROV-001)
78    #[error("Provenance error: {0}")]
79    Provenance(#[from] crate::provenance::ProvenanceError),
80
81    /// Validation error (PMAT-266: naming convention, schema validation)
82    #[error("Validation error: {0}")]
83    Validation(String),
84}
85
86#[cfg(test)]
87mod tests {
88    use super::*;
89
90    #[test]
91    fn test_error_display() {
92        let err = Error::CommandFailed {
93            command: "apr run".to_string(),
94            exit_code: 1,
95            stderr: "error".to_string(),
96        };
97        assert!(err.to_string().contains("apr run"));
98        assert!(err.to_string().contains("exit code: 1"));
99    }
100
101    #[test]
102    fn test_timeout_error() {
103        let err = Error::Timeout {
104            command: "apr serve".to_string(),
105            timeout_ms: 30000,
106        };
107        assert!(err.to_string().contains("30000ms"));
108    }
109
110    #[test]
111    fn test_validation_error() {
112        let err = Error::Validation("Invalid playbook name".to_string());
113        assert!(err.to_string().contains("Validation error"));
114        assert!(err.to_string().contains("Invalid playbook name"));
115    }
116}