Skip to main content

gba_core/
error.rs

1//! Error types for the GBA core engine.
2//!
3//! This module defines error types for engine operations including
4//! configuration, prompt rendering, agent execution, and I/O operations.
5
6use std::path::PathBuf;
7
8/// Error type for engine operations.
9#[derive(Debug, thiserror::Error)]
10#[non_exhaustive]
11pub enum EngineError {
12    /// Configuration error.
13    #[error("configuration error: {0}")]
14    ConfigError(String),
15
16    /// Error from the prompt manager.
17    #[error("prompt error: {0}")]
18    PromptError(#[from] gba_pm::PromptError),
19
20    /// Error from the Claude agent SDK.
21    #[error("agent error: {0}")]
22    AgentError(#[from] claude_agent_sdk_rs::ClaudeError),
23
24    /// I/O error during file operations.
25    #[error("I/O error at '{path}': {source}")]
26    IoError {
27        /// The path that caused the error.
28        path: PathBuf,
29        /// The underlying I/O error.
30        #[source]
31        source: std::io::Error,
32    },
33
34    /// YAML parsing error.
35    #[error("YAML parse error at '{path}': {source}")]
36    YamlError {
37        /// The path that caused the error.
38        path: PathBuf,
39        /// The underlying YAML error.
40        #[source]
41        source: serde_yaml::Error,
42    },
43
44    /// Task configuration not found.
45    #[error("task configuration not found for task kind: {0}")]
46    TaskConfigNotFound(String),
47}
48
49impl EngineError {
50    /// Create a new I/O error with path context.
51    pub fn io_error(path: impl Into<PathBuf>, source: std::io::Error) -> Self {
52        Self::IoError {
53            path: path.into(),
54            source,
55        }
56    }
57
58    /// Create a new YAML error with path context.
59    pub fn yaml_error(path: impl Into<PathBuf>, source: serde_yaml::Error) -> Self {
60        Self::YamlError {
61            path: path.into(),
62            source,
63        }
64    }
65
66    /// Create a new configuration error.
67    pub fn config_error(message: impl Into<String>) -> Self {
68        Self::ConfigError(message.into())
69    }
70}
71
72/// Result type alias for engine operations.
73pub type Result<T> = std::result::Result<T, EngineError>;
74
75#[cfg(test)]
76mod tests {
77    use super::*;
78
79    #[test]
80    fn test_should_display_config_error() {
81        let err = EngineError::config_error("invalid model");
82        assert_eq!(err.to_string(), "configuration error: invalid model");
83    }
84
85    #[test]
86    fn test_should_display_io_error_with_path() {
87        let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
88        let err = EngineError::io_error("/path/to/config.yml", io_err);
89        assert!(err.to_string().contains("/path/to/config.yml"));
90        assert!(err.to_string().contains("I/O error"));
91    }
92
93    #[test]
94    fn test_should_display_task_config_not_found() {
95        let err = EngineError::TaskConfigNotFound("custom_task".to_string());
96        assert!(err.to_string().contains("custom_task"));
97    }
98}