ricecoder_agents/
error.rs

1//! Error types for the agent framework
2
3use thiserror::Error;
4
5/// Errors that can occur during agent operations
6#[derive(Debug, Clone, Error)]
7pub enum AgentError {
8    /// Agent not found
9    #[error("Agent not found: {0}")]
10    NotFound(String),
11
12    /// Agent execution failed
13    #[error("Agent execution failed: {0}")]
14    ExecutionFailed(String),
15
16    /// Agent timeout
17    #[error("Agent timeout after {0}ms")]
18    Timeout(u64),
19
20    /// Configuration error
21    #[error("Configuration error: {0}")]
22    ConfigError(String),
23
24    /// Path resolution error
25    #[error("Path resolution error: {0}")]
26    PathError(String),
27
28    /// Provider error
29    #[error("Provider error: {0}")]
30    ProviderError(String),
31
32    /// Serialization error
33    #[error("Serialization error: {0}")]
34    SerializationError(String),
35
36    /// Invalid input
37    #[error("Invalid input: {0}")]
38    InvalidInput(String),
39
40    /// Internal error
41    #[error("Internal error: {0}")]
42    Internal(String),
43}
44
45impl AgentError {
46    /// Create a new NotFound error
47    pub fn not_found(agent_id: impl Into<String>) -> Self {
48        Self::NotFound(agent_id.into())
49    }
50
51    /// Create a new ExecutionFailed error
52    pub fn execution_failed(reason: impl Into<String>) -> Self {
53        Self::ExecutionFailed(reason.into())
54    }
55
56    /// Create a new Timeout error
57    pub fn timeout(ms: u64) -> Self {
58        Self::Timeout(ms)
59    }
60
61    /// Create a new ConfigError
62    pub fn config_error(reason: impl Into<String>) -> Self {
63        Self::ConfigError(reason.into())
64    }
65
66    /// Create a new PathError
67    pub fn path_error(reason: impl Into<String>) -> Self {
68        Self::PathError(reason.into())
69    }
70
71    /// Create a new ProviderError
72    pub fn provider_error(reason: impl Into<String>) -> Self {
73        Self::ProviderError(reason.into())
74    }
75
76    /// Create a new InvalidInput error
77    pub fn invalid_input(reason: impl Into<String>) -> Self {
78        Self::InvalidInput(reason.into())
79    }
80
81    /// Create a new Internal error
82    pub fn internal(reason: impl Into<String>) -> Self {
83        Self::Internal(reason.into())
84    }
85}
86
87/// Result type for agent operations
88pub type Result<T> = std::result::Result<T, AgentError>;
89
90#[cfg(test)]
91mod tests {
92    use super::*;
93
94    #[test]
95    fn test_agent_error_not_found() {
96        let error = AgentError::not_found("test-agent");
97        assert!(matches!(error, AgentError::NotFound(_)));
98        assert_eq!(error.to_string(), "Agent not found: test-agent");
99    }
100
101    #[test]
102    fn test_agent_error_execution_failed() {
103        let error = AgentError::execution_failed("execution error");
104        assert!(matches!(error, AgentError::ExecutionFailed(_)));
105        assert_eq!(error.to_string(), "Agent execution failed: execution error");
106    }
107
108    #[test]
109    fn test_agent_error_timeout() {
110        let error = AgentError::timeout(5000);
111        assert!(matches!(error, AgentError::Timeout(_)));
112        assert_eq!(error.to_string(), "Agent timeout after 5000ms");
113    }
114
115    #[test]
116    fn test_agent_error_config_error() {
117        let error = AgentError::config_error("invalid config");
118        assert!(matches!(error, AgentError::ConfigError(_)));
119        assert_eq!(error.to_string(), "Configuration error: invalid config");
120    }
121
122    #[test]
123    fn test_agent_error_path_error() {
124        let error = AgentError::path_error("path not found");
125        assert!(matches!(error, AgentError::PathError(_)));
126        assert_eq!(error.to_string(), "Path resolution error: path not found");
127    }
128
129    #[test]
130    fn test_agent_error_provider_error() {
131        let error = AgentError::provider_error("provider unavailable");
132        assert!(matches!(error, AgentError::ProviderError(_)));
133        assert_eq!(error.to_string(), "Provider error: provider unavailable");
134    }
135
136    #[test]
137    fn test_agent_error_invalid_input() {
138        let error = AgentError::invalid_input("invalid data");
139        assert!(matches!(error, AgentError::InvalidInput(_)));
140        assert_eq!(error.to_string(), "Invalid input: invalid data");
141    }
142
143    #[test]
144    fn test_agent_error_internal() {
145        let error = AgentError::internal("internal error");
146        assert!(matches!(error, AgentError::Internal(_)));
147        assert_eq!(error.to_string(), "Internal error: internal error");
148    }
149
150    #[test]
151    fn test_agent_error_serialization_error() {
152        let error = AgentError::SerializationError("invalid json".to_string());
153        assert!(matches!(error, AgentError::SerializationError(_)));
154    }
155
156    #[test]
157    fn test_agent_error_clone() {
158        let error = AgentError::not_found("test-agent");
159        let cloned = error.clone();
160        assert_eq!(error.to_string(), cloned.to_string());
161    }
162
163    #[test]
164    fn test_error_display_trait() {
165        let error = AgentError::not_found("agent-1");
166        let display_string = format!("{}", error);
167        assert_eq!(display_string, "Agent not found: agent-1");
168    }
169
170    #[test]
171    fn test_error_debug_trait() {
172        let error = AgentError::timeout(1000);
173        let debug_string = format!("{:?}", error);
174        assert!(debug_string.contains("Timeout"));
175    }
176
177    #[test]
178    fn test_result_type_ok() {
179        let result: Result<i32> = Ok(42);
180        assert!(result.is_ok());
181        assert_eq!(result.unwrap(), 42);
182    }
183
184    #[test]
185    fn test_result_type_err() {
186        let result: Result<i32> = Err(AgentError::not_found("test"));
187        assert!(result.is_err());
188    }
189}