Skip to main content

aurora_db/
error.rs

1use color_eyre::eyre::Report;
2use serde::{Deserialize, Serialize};
3use std::fmt;
4
5#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
6pub enum ErrorCode {
7    InternalError,
8    IoError,
9    StorageError,
10    SerializationError,
11    CollectionNotFound,
12    CollectionAlreadyExists,
13    UniqueConstraintViolation,
14    ProtocolError,
15    InvalidQuery,
16    InvalidOperation,
17    InvalidInput,
18    NotFound,
19    InvalidKey,
20    InvalidValue,
21    InvalidDefinition,
22    QueryError,
23    SchemaError,
24    TypeError,
25    UndefinedVariable,
26    ValidationError,
27    SecurityError,
28    Timeout,
29    FilterParseError,
30}
31
32#[derive(Debug)]
33pub struct AqlError {
34    pub code: ErrorCode,
35    pub message: String,
36    pub source: Option<Report>,
37    pub line: Option<usize>,
38    pub column: Option<usize>,
39}
40
41impl AqlError {
42    pub fn new(code: ErrorCode, message: impl Into<String>) -> Self {
43        Self {
44            code,
45            message: message.into(),
46            source: None,
47            line: None,
48            column: None,
49        }
50    }
51
52    pub fn with_location(mut self, line: usize, column: usize) -> Self {
53        self.line = Some(line);
54        self.column = Some(column);
55        self
56    }
57
58    pub fn from_error<E>(code: ErrorCode, message: impl Into<String>, err: E) -> Self
59    where
60        E: Into<Report>,
61    {
62        Self {
63            code,
64            message: message.into(),
65            source: Some(err.into()),
66            line: None,
67            column: None,
68        }
69    }
70
71    // Convenience constructors
72    pub fn invalid_operation(msg: impl Into<String>) -> Self {
73        Self::new(ErrorCode::InvalidOperation, msg)
74    }
75
76    pub fn schema_error(msg: impl Into<String>) -> Self {
77        Self::new(ErrorCode::SchemaError, msg)
78    }
79}
80
81impl fmt::Display for AqlError {
82    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83        if let (Some(line), Some(col)) = (self.line, self.column) {
84            write!(
85                f,
86                "[{:?}] {} (line {}, col {})",
87                self.code, self.message, line, col
88            )
89        } else {
90            write!(f, "[{:?}] {}", self.code, self.message)
91        }
92    }
93}
94
95impl std::error::Error for AqlError {
96    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
97        self.source
98            .as_ref()
99            .map(|r| r.as_ref() as &(dyn std::error::Error + 'static))
100    }
101}
102
103// Result alias
104pub type Result<T> = std::result::Result<T, AqlError>;
105
106impl From<std::io::Error> for AqlError {
107    fn from(err: std::io::Error) -> Self {
108        Self::from_error(ErrorCode::IoError, "IO Error", err)
109    }
110}
111
112impl From<sled::Error> for AqlError {
113    fn from(err: sled::Error) -> Self {
114        Self::from_error(ErrorCode::StorageError, "Storage Error", err)
115    }
116}
117
118impl From<serde_json::Error> for AqlError {
119    fn from(err: serde_json::Error) -> Self {
120        Self::from_error(ErrorCode::SerializationError, "Serialization Error", err)
121    }
122}
123
124impl From<bincode::Error> for AqlError {
125    fn from(err: bincode::Error) -> Self {
126        Self::from_error(ErrorCode::SerializationError, "Bincode Error", err)
127    }
128}
129
130impl From<std::time::SystemTimeError> for AqlError {
131    fn from(err: std::time::SystemTimeError) -> Self {
132        Self::from_error(ErrorCode::InternalError, "System Time Error", err)
133    }
134}
135
136impl From<zip::result::ZipError> for AqlError {
137    fn from(err: zip::result::ZipError) -> Self {
138        Self::from_error(ErrorCode::InternalError, "Zip Error", err)
139    }
140}
141
142impl From<csv::Error> for AqlError {
143    fn from(err: csv::Error) -> Self {
144        Self::from_error(ErrorCode::InternalError, "CSV Error", err)
145    }
146}