1use thiserror::Error;
4
5mod reporter;
6pub use reporter::ErrorReporter;
7
8#[derive(Debug, Clone, PartialEq, Eq, Default)]
10pub struct Span {
11 pub start: usize,
12 pub end: usize,
13}
14
15impl Span {
16 pub fn new(start: usize, end: usize) -> Self {
18 Self { start, end }
19 }
20}
21
22#[derive(Debug, Error)]
24pub enum GentError {
25 #[error("Syntax error at {span:?}: {message}")]
27 SyntaxError { message: String, span: Span },
28
29 #[error("Unexpected token: expected {expected}, found {found}")]
31 UnexpectedToken {
32 expected: String,
33 found: String,
34 span: Span,
35 },
36
37 #[error("Undefined agent: '{name}'")]
39 UndefinedAgent { name: String, span: Span },
40
41 #[error("Agent '{agent}' missing required field: '{field}'")]
43 MissingAgentField {
44 agent: String,
45 field: String,
46 span: Span,
47 },
48
49 #[error("Type error: expected {expected}, got {got}")]
51 TypeError {
52 expected: String,
53 got: String,
54 span: Span,
55 },
56
57 #[error("LLM error: {message}")]
59 LLMError { message: String },
60
61 #[error("Could not read file '{path}': {source}")]
63 FileReadError {
64 path: String,
65 #[source]
66 source: std::io::Error,
67 },
68
69 #[error("API error: {message}")]
71 ApiError { message: String },
72
73 #[error("Missing API key for {provider}. Set {provider}_API_KEY environment variable.")]
75 MissingApiKey { provider: String },
76
77 #[error("Agent exceeded maximum steps ({limit})")]
79 MaxStepsExceeded { limit: u32 },
80
81 #[error("Parallel block '{name}' timed out after {timeout_ms}ms")]
83 ParallelTimeout { name: String, timeout_ms: u64 },
84
85 #[error("Unknown tool: '{name}'")]
87 UnknownTool { name: String, span: Span },
88
89 #[error("Tool '{tool}' failed: {message}")]
91 ToolError { tool: String, message: String },
92
93 #[error("Undefined variable: {name}")]
95 UndefinedVariable { name: String, span: Span },
96
97 #[error("Undefined property: {property} on {type_name}")]
99 UndefinedProperty {
100 property: String,
101 type_name: String,
102 span: Span,
103 },
104
105 #[error("Index out of bounds: {index} (length: {length})")]
107 IndexOutOfBounds {
108 index: i64,
109 length: usize,
110 span: Span,
111 },
112
113 #[error("Cannot index into {type_name}")]
115 NotIndexable { type_name: String, span: Span },
116
117 #[error("Invalid operand types: {left} {op} {right}")]
119 InvalidOperands {
120 op: String,
121 left: String,
122 right: String,
123 span: Span,
124 },
125
126 #[error("Division by zero")]
128 DivisionByZero { span: Span },
129
130 #[error("Expected {expected} arguments, got {got}")]
132 WrongArgumentCount {
133 expected: usize,
134 got: usize,
135 span: Span,
136 },
137
138 #[error("Type mismatch for parameter '{param}': expected {expected}, got {got}")]
140 ArgumentTypeMismatch {
141 param: String,
142 expected: String,
143 got: String,
144 span: Span,
145 },
146
147 #[error("Output validation error: {message}\nExpected schema: {expected}\nGot: {got}")]
149 OutputValidationError {
150 message: String,
151 expected: String,
152 got: String,
153 },
154}
155
156impl GentError {
157 pub fn span(&self) -> Option<&Span> {
159 match self {
160 GentError::SyntaxError { span, .. } => Some(span),
161 GentError::UnexpectedToken { span, .. } => Some(span),
162 GentError::UndefinedAgent { span, .. } => Some(span),
163 GentError::MissingAgentField { span, .. } => Some(span),
164 GentError::TypeError { span, .. } => Some(span),
165 GentError::UnknownTool { span, .. } => Some(span),
166 GentError::UndefinedVariable { span, .. } => Some(span),
167 GentError::UndefinedProperty { span, .. } => Some(span),
168 GentError::IndexOutOfBounds { span, .. } => Some(span),
169 GentError::NotIndexable { span, .. } => Some(span),
170 GentError::InvalidOperands { span, .. } => Some(span),
171 GentError::DivisionByZero { span } => Some(span),
172 GentError::WrongArgumentCount { span, .. } => Some(span),
173 GentError::ArgumentTypeMismatch { span, .. } => Some(span),
174 GentError::LLMError { .. } => None,
175 GentError::FileReadError { .. } => None,
176 GentError::ApiError { .. } => None,
177 GentError::MissingApiKey { .. } => None,
178 GentError::MaxStepsExceeded { .. } => None,
179 GentError::ParallelTimeout { .. } => None,
180 GentError::ToolError { .. } => None,
181 GentError::OutputValidationError { .. } => None,
182 }
183 }
184}
185
186pub type GentResult<T> = Result<T, GentError>;