ai_agent/
errors.rs

1//! Error types for the AI-Native Code Agent
2
3use thiserror::Error;
4
5/// Main agent error type
6#[derive(Debug, Error, Clone)]
7pub enum AgentError {
8    #[error("Model error: {0}")]
9    ModelError(#[from] ModelError),
10
11    #[error("Tool error: {0}")]
12    ToolError(#[from] ToolError),
13
14    #[error("Network error: {0}")]
15    NetworkError(String),
16
17    #[error("Timeout error")]
18    TimeoutError,
19
20    #[error("Configuration error: {0}")]
21    ConfigError(String),
22
23    #[error("Unknown error: {0}")]
24    UnknownError(String),
25}
26
27/// Model-related errors
28#[derive(Debug, Error, Clone)]
29pub enum ModelError {
30    #[error("API error: {0}")]
31    APIError(String),
32
33    #[error("Authentication error: {0}")]
34    AuthenticationError(String),
35
36    #[error("Rate limited")]
37    RateLimited,
38
39    #[error("Invalid response: {0}")]
40    InvalidResponse(String),
41
42    #[error("Model not supported: {0}")]
43    ModelNotSupported(String),
44
45    #[error("Quota exceeded")]
46    QuotaExceeded,
47
48    #[error("Network error: {0}")]
49    NetworkError(String),
50}
51
52/// Tool-related errors
53#[derive(Debug, Error, Clone)]
54pub enum ToolError {
55    #[error("Tool not found: {0}")]
56    ToolNotFound(String),
57
58    #[error("Execution error: {0}")]
59    ExecutionError(String),
60
61    #[error("Invalid parameters: {0}")]
62    InvalidParameters(String),
63
64    #[error("Permission denied: {0}")]
65    PermissionDenied(String),
66
67    #[error("Timeout error")]
68    TimeoutError,
69}
70
71/// Error handler with retry logic
72pub struct ErrorHandler {
73    pub max_retries: u32,
74    pub retry_delay_seconds: u64,
75}
76
77impl ErrorHandler {
78    pub fn new(max_retries: u32, retry_delay_seconds: u64) -> Self {
79        Self {
80            max_retries,
81            retry_delay_seconds,
82        }
83    }
84
85    pub async fn handle_with_retry<F, T, Fut>(&self, operation: F) -> Result<T, AgentError>
86    where
87        F: Fn() -> Fut,
88        Fut: std::future::Future<Output = Result<T, AgentError>>,
89    {
90        let mut last_error = None;
91
92        for attempt in 0..=self.max_retries {
93            match operation().await {
94                Ok(result) => return Ok(result),
95                Err(error) => {
96                    last_error = Some(error.clone());
97
98                    if attempt < self.max_retries && self.should_retry(&error) {
99                        tokio::time::sleep(tokio::time::Duration::from_secs(
100                            self.retry_delay_seconds * (attempt as u64 + 1)
101                        )).await;
102                        continue;
103                    } else {
104                        break;
105                    }
106                }
107            }
108        }
109
110        Err(last_error.unwrap_or(AgentError::UnknownError("Unknown error".to_string())))
111    }
112
113    fn should_retry(&self, error: &AgentError) -> bool {
114        match error {
115            AgentError::NetworkError(_) => true,
116            AgentError::TimeoutError => true,
117            AgentError::ModelError(ModelError::RateLimited) => true,
118            _ => false,
119        }
120    }
121}