Skip to main content

agentforge_core/
error.rs

1use thiserror::Error;
2
3#[derive(Debug, Error)]
4pub enum AgentForgeError {
5    #[error("Parse error: {0}")]
6    ParseError(String),
7
8    #[error("Validation error: {0}")]
9    ValidationError(String),
10
11    #[error("Invalid format: {0}")]
12    InvalidFormat(String),
13
14    #[error("Database error: {0}")]
15    DatabaseError(String),
16
17    #[error("LLM error: {provider} - {message}")]
18    LlmError { provider: String, message: String },
19
20    #[error("LLM error: judge model and agent model must differ (both are {model})")]
21    CircularBiasError { model: String },
22
23    #[error("Scoring error: {0}")]
24    ScoringError(String),
25
26    #[error("Optimization error: {0}")]
27    OptimizationError(String),
28
29    #[error("Promotion failed: {reason}")]
30    PromotionFailed { reason: String },
31
32    #[error("Gatekeeper failed - score gate: current={current:.3} champion={champion:.3} required_delta={required:.3}")]
33    ScoreGateFailed {
34        current: f64,
35        champion: f64,
36        required: f64,
37    },
38
39    #[error(
40        "Gatekeeper failed - regression gate: pass_rate={pass_rate:.3} required={required:.3}"
41    )]
42    RegressionGateFailed { pass_rate: f64, required: f64 },
43
44    #[error("Gatekeeper failed - stability gate: only {seeds} seeds run, need {required}")]
45    StabilityGateFailed { seeds: usize, required: usize },
46
47    #[error("Not found: {resource} with id {id}")]
48    NotFound { resource: &'static str, id: String },
49
50    #[error("Configuration error: {0}")]
51    ConfigError(String),
52
53    #[error("IO error: {0}")]
54    IoError(#[from] std::io::Error),
55
56    #[error("Serialization error: {0}")]
57    SerializationError(String),
58
59    #[error("HTTP error: {0}")]
60    HttpError(String),
61
62    #[error("Timeout after {seconds}s")]
63    Timeout { seconds: u64 },
64
65    #[error("Rate limit exceeded for provider {provider}")]
66    RateLimitExceeded { provider: String },
67}
68
69/// Convenience alias for `Result<T, AgentForgeError>`.
70pub type Result<T> = std::result::Result<T, AgentForgeError>;
71
72impl From<serde_json::Error> for AgentForgeError {
73    fn from(e: serde_json::Error) -> Self {
74        AgentForgeError::SerializationError(e.to_string())
75    }
76}
77
78#[cfg(test)]
79mod tests {
80    use super::*;
81
82    #[test]
83    fn error_display_score_gate() {
84        let err = AgentForgeError::ScoreGateFailed {
85            current: 0.82,
86            champion: 0.85,
87            required: 0.03,
88        };
89        let msg = err.to_string();
90        assert!(msg.contains("score gate"));
91        assert!(msg.contains("0.820"));
92    }
93
94    #[test]
95    fn error_display_circular_bias() {
96        let err = AgentForgeError::CircularBiasError {
97            model: "gpt-4o".to_string(),
98        };
99        assert!(err.to_string().contains("gpt-4o"));
100    }
101}