1use serde::{Deserialize, Serialize};
7use std::fmt;
8use thiserror::Error;
9
10#[derive(Error, Debug, Clone, PartialEq, Serialize, Deserialize)]
12pub struct ExpressionError {
13 pub error_type: ExpressionErrorType,
15 pub message: String,
17 pub position: Option<ExpressionPosition>,
19}
20
21#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
23pub enum ExpressionErrorType {
24 TypeError,
26 UndefinedVariable,
28 UndefinedFunction,
30 UnknownFunction,
32 FunctionError,
34 ArgumentCountError,
36 InvalidArgumentCount,
38 Overflow,
40 IndexOutOfBounds,
42 NullError,
44 SyntaxError,
46 InvalidOperation,
48 PropertyNotFound,
50 RuntimeError,
52 UnsupportedOperation,
54 TypeConversionError,
56 OperatorError,
58 LabelNotFound,
60 EdgeNotFound,
62 PathError,
64 RangeError,
66 AggregateError,
68 ValidationError,
70 FunctionExecutionError,
72}
73
74impl std::fmt::Display for ExpressionErrorType {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 match self {
77 ExpressionErrorType::TypeError => write!(f, "Type error"),
78 ExpressionErrorType::UndefinedVariable => write!(f, "Undefined variable"),
79 ExpressionErrorType::UndefinedFunction => write!(f, "Undefined function"),
80 ExpressionErrorType::UnknownFunction => write!(f, "Unknown function"),
81 ExpressionErrorType::FunctionError => write!(f, "Function error"),
82 ExpressionErrorType::ArgumentCountError => write!(f, "Argument count error"),
83 ExpressionErrorType::InvalidArgumentCount => write!(f, "Invalid argument count"),
84 ExpressionErrorType::Overflow => write!(f, "Overflow error"),
85 ExpressionErrorType::IndexOutOfBounds => write!(f, "Index out of bounds"),
86 ExpressionErrorType::NullError => write!(f, "Null error"),
87 ExpressionErrorType::SyntaxError => write!(f, "Syntax error"),
88 ExpressionErrorType::InvalidOperation => write!(f, "Invalid operation"),
89 ExpressionErrorType::PropertyNotFound => write!(f, "Property not found"),
90 ExpressionErrorType::RuntimeError => write!(f, "Runtime error"),
91 ExpressionErrorType::UnsupportedOperation => write!(f, "Unsupported operation"),
92 ExpressionErrorType::TypeConversionError => write!(f, "Type conversion error"),
93 ExpressionErrorType::OperatorError => write!(f, "Operator error"),
94 ExpressionErrorType::LabelNotFound => write!(f, "Label not found"),
95 ExpressionErrorType::EdgeNotFound => write!(f, "Edge not found"),
96 ExpressionErrorType::PathError => write!(f, "Path error"),
97 ExpressionErrorType::RangeError => write!(f, "Range error"),
98 ExpressionErrorType::AggregateError => write!(f, "Aggregate error"),
99 ExpressionErrorType::ValidationError => write!(f, "Validation error"),
100 ExpressionErrorType::FunctionExecutionError => write!(f, "Function execution error"),
101 }
102 }
103}
104
105#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
107pub struct ExpressionPosition {
108 pub line: usize,
110 pub column: usize,
112 pub offset: usize,
114 pub length: usize,
116}
117
118impl ExpressionError {
119 pub fn new(error_type: ExpressionErrorType, message: impl Into<String>) -> Self {
121 Self {
122 error_type,
123 message: message.into(),
124 position: None,
125 }
126 }
127
128 pub fn with_position(
130 mut self,
131 line: usize,
132 column: usize,
133 offset: usize,
134 length: usize,
135 ) -> Self {
136 self.position = Some(ExpressionPosition {
137 line,
138 column,
139 offset,
140 length,
141 });
142 self
143 }
144
145 pub fn type_error(message: impl Into<String>) -> Self {
147 Self::new(ExpressionErrorType::TypeError, message)
148 }
149
150 pub fn undefined_variable(name: impl Into<String>) -> Self {
152 Self::new(
153 ExpressionErrorType::UndefinedVariable,
154 format!("Undefined variable: {}", name.into()),
155 )
156 }
157
158 pub fn undefined_parameter(name: impl Into<String>) -> Self {
160 Self::new(
161 ExpressionErrorType::UndefinedVariable,
162 format!("Undefined parameter: {}", name.into()),
163 )
164 }
165
166 pub fn undefined_function(name: impl Into<String>) -> Self {
168 Self::new(
169 ExpressionErrorType::UndefinedFunction,
170 format!("Undefined function: {}", name.into()),
171 )
172 }
173
174 pub fn argument_count_error(expected: usize, actual: usize) -> Self {
176 Self::new(
177 ExpressionErrorType::ArgumentCountError,
178 format!(
179 "Argument count error: expected {}, got {}",
180 expected, actual
181 ),
182 )
183 }
184
185 pub fn overflow(message: impl Into<String>) -> Self {
187 Self::new(ExpressionErrorType::Overflow, message)
188 }
189
190 pub fn index_out_of_bounds(index: isize, size: usize) -> Self {
192 Self::new(
193 ExpressionErrorType::IndexOutOfBounds,
194 format!("Index out of bounds: index {}, size {}", index, size),
195 )
196 }
197
198 pub fn null_error(message: impl Into<String>) -> Self {
200 Self::new(ExpressionErrorType::NullError, message)
201 }
202
203 pub fn syntax_error(message: impl Into<String>) -> Self {
205 Self::new(ExpressionErrorType::SyntaxError, message)
206 }
207
208 pub fn runtime_error(message: impl Into<String>) -> Self {
210 Self::new(ExpressionErrorType::RuntimeError, message)
211 }
212
213 pub fn function_error(message: impl Into<String>) -> Self {
215 Self::new(ExpressionErrorType::FunctionError, message)
216 }
217
218 pub fn invalid_operation(message: impl Into<String>) -> Self {
220 Self::new(ExpressionErrorType::InvalidOperation, message)
221 }
222
223 pub fn property_not_found(message: impl Into<String>) -> Self {
225 Self::new(ExpressionErrorType::PropertyNotFound, message)
226 }
227
228 pub fn unknown_function(name: impl Into<String>) -> Self {
230 Self::new(
231 ExpressionErrorType::UnknownFunction,
232 format!("Unknown function: {}", name.into()),
233 )
234 }
235
236 pub fn invalid_argument_count(name: impl Into<String>) -> Self {
238 Self::new(
239 ExpressionErrorType::InvalidArgumentCount,
240 format!("Invalid argument count: {}", name.into()),
241 )
242 }
243
244 pub fn invalid_arity(name: &str, expected: usize, actual: usize) -> Self {
246 Self::new(
247 ExpressionErrorType::InvalidArgumentCount,
248 format!(
249 "function '{}' expects {} argument(s), got {}",
250 name, expected, actual
251 ),
252 )
253 }
254
255 pub fn unsupported_operation(
257 operation: impl Into<String>,
258 suggestion: impl Into<String>,
259 ) -> Self {
260 Self::new(
261 ExpressionErrorType::UnsupportedOperation,
262 format!(
263 "Unsupported operation: {}, suggestion: {}",
264 operation.into(),
265 suggestion.into()
266 ),
267 )
268 }
269
270 pub fn type_conversion_error(from_type: impl Into<String>, to_type: impl Into<String>) -> Self {
272 Self::new(
273 ExpressionErrorType::TypeConversionError,
274 format!(
275 "Type conversion error: cannot convert from {} to {}",
276 from_type.into(),
277 to_type.into()
278 ),
279 )
280 }
281
282 pub fn operator_error(operator: impl Into<String>, message: impl Into<String>) -> Self {
284 Self::new(
285 ExpressionErrorType::OperatorError,
286 format!("Operator error: {}: {}", operator.into(), message.into()),
287 )
288 }
289
290 pub fn label_not_found(label: impl Into<String>) -> Self {
292 Self::new(
293 ExpressionErrorType::LabelNotFound,
294 format!("Label not found: {}", label.into()),
295 )
296 }
297
298 pub fn edge_not_found(edge: impl Into<String>) -> Self {
300 Self::new(
301 ExpressionErrorType::EdgeNotFound,
302 format!("Edge not found: {}", edge.into()),
303 )
304 }
305
306 pub fn path_error(message: impl Into<String>) -> Self {
308 Self::new(ExpressionErrorType::PathError, message)
309 }
310
311 pub fn range_error(message: impl Into<String>) -> Self {
313 Self::new(ExpressionErrorType::RangeError, message)
314 }
315
316 pub fn aggregate_error(message: impl Into<String>) -> Self {
318 Self::new(ExpressionErrorType::AggregateError, message)
319 }
320
321 pub fn validation_error(message: impl Into<String>) -> Self {
323 Self::new(ExpressionErrorType::ValidationError, message)
324 }
325}
326
327impl fmt::Display for ExpressionError {
328 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
329 write!(f, "{:?}: {}", self.error_type, self.message)
330 }
331}
332
333impl From<ExpressionError> for linkrs_core::error::DBError {
334 fn from(e: ExpressionError) -> Self {
335 let msg = e.to_string();
336 Self::expression(msg).with_source(Box::new(e))
337 }
338}