nirv_engine/utils/
error.rs

1use thiserror::Error;
2
3/// Main error type for NIRV Engine
4#[derive(Debug, Error)]
5pub enum NirvError {
6    #[error("Protocol error: {0}")]
7    Protocol(#[from] ProtocolError),
8    
9    #[error("Query parsing error: {0}")]
10    QueryParsing(#[from] QueryParsingError),
11    
12    #[error("Connector error: {0}")]
13    Connector(#[from] ConnectorError),
14    
15    #[error("Dispatcher error: {0}")]
16    Dispatcher(#[from] DispatcherError),
17    
18    #[error("Configuration error: {0}")]
19    Configuration(String),
20    
21    #[error("Internal error: {0}")]
22    Internal(String),
23}
24
25/// Protocol-specific errors
26#[derive(Debug, Error)]
27pub enum ProtocolError {
28    #[error("Connection failed: {0}")]
29    ConnectionFailed(String),
30    
31    #[error("Authentication failed: {0}")]
32    AuthenticationFailed(String),
33    
34    #[error("Invalid message format: {0}")]
35    InvalidMessageFormat(String),
36    
37    #[error("Protocol version not supported: {0}")]
38    UnsupportedVersion(String),
39    
40    #[error("Unsupported feature: {0}")]
41    UnsupportedFeature(String),
42    
43    #[error("Connection closed unexpectedly")]
44    ConnectionClosed,
45}
46
47/// Query parsing errors
48#[derive(Debug, Error)]
49pub enum QueryParsingError {
50    #[error("Invalid SQL syntax: {0}")]
51    InvalidSyntax(String),
52    
53    #[error("Unsupported SQL feature: {0}")]
54    UnsupportedFeature(String),
55    
56    #[error("Missing source specification in query")]
57    MissingSource,
58    
59    #[error("Invalid source format: {0}")]
60    InvalidSourceFormat(String),
61    
62    #[error("Ambiguous column reference: {0}")]
63    AmbiguousColumn(String),
64}
65
66/// Connector-specific errors
67#[derive(Debug, Error)]
68pub enum ConnectorError {
69    #[error("Connection to backend failed: {0}")]
70    ConnectionFailed(String),
71    
72    #[error("Query execution failed: {0}")]
73    QueryExecutionFailed(String),
74    
75    #[error("Schema retrieval failed: {0}")]
76    SchemaRetrievalFailed(String),
77    
78    #[error("Unsupported operation: {0}")]
79    UnsupportedOperation(String),
80    
81    #[error("Timeout occurred: {0}")]
82    Timeout(String),
83    
84    #[error("Authentication failed: {0}")]
85    AuthenticationFailed(String),
86}
87
88/// Dispatcher errors
89#[derive(Debug, Error)]
90pub enum DispatcherError {
91    #[error("Data object type not registered: {0}")]
92    UnregisteredObjectType(String),
93    
94    #[error("No suitable connector found for query")]
95    NoSuitableConnector,
96    
97    #[error("Query routing failed: {0}")]
98    RoutingFailed(String),
99    
100    #[error("Cross-connector join not supported")]
101    CrossConnectorJoinUnsupported,
102    
103    #[error("Connector registration failed: {0}")]
104    RegistrationFailed(String),
105}
106
107/// Result type alias for NIRV operations
108pub type NirvResult<T> = Result<T, NirvError>;#
109[cfg(test)]
110mod tests {
111    use super::*;
112
113    #[test]
114    fn test_nirv_error_from_protocol_error() {
115        let protocol_error = ProtocolError::ConnectionFailed("Test connection failed".to_string());
116        let nirv_error: NirvError = protocol_error.into();
117        
118        match nirv_error {
119            NirvError::Protocol(ProtocolError::ConnectionFailed(msg)) => {
120                assert_eq!(msg, "Test connection failed");
121            }
122            _ => panic!("Expected Protocol error"),
123        }
124    }
125
126    #[test]
127    fn test_nirv_error_from_query_parsing_error() {
128        let parsing_error = QueryParsingError::InvalidSyntax("Invalid SQL".to_string());
129        let nirv_error: NirvError = parsing_error.into();
130        
131        match nirv_error {
132            NirvError::QueryParsing(QueryParsingError::InvalidSyntax(msg)) => {
133                assert_eq!(msg, "Invalid SQL");
134            }
135            _ => panic!("Expected QueryParsing error"),
136        }
137    }
138
139    #[test]
140    fn test_nirv_error_from_connector_error() {
141        let connector_error = ConnectorError::QueryExecutionFailed("Query failed".to_string());
142        let nirv_error: NirvError = connector_error.into();
143        
144        match nirv_error {
145            NirvError::Connector(ConnectorError::QueryExecutionFailed(msg)) => {
146                assert_eq!(msg, "Query failed");
147            }
148            _ => panic!("Expected Connector error"),
149        }
150    }
151
152    #[test]
153    fn test_nirv_error_from_dispatcher_error() {
154        let dispatcher_error = DispatcherError::UnregisteredObjectType("unknown_type".to_string());
155        let nirv_error: NirvError = dispatcher_error.into();
156        
157        match nirv_error {
158            NirvError::Dispatcher(DispatcherError::UnregisteredObjectType(msg)) => {
159                assert_eq!(msg, "unknown_type");
160            }
161            _ => panic!("Expected Dispatcher error"),
162        }
163    }
164
165    #[test]
166    fn test_error_display() {
167        let error = NirvError::Configuration("Invalid config".to_string());
168        let error_string = format!("{}", error);
169        assert!(error_string.contains("Configuration error: Invalid config"));
170    }
171
172    #[test]
173    fn test_nirv_result_type() {
174        let success: NirvResult<String> = Ok("success".to_string());
175        let failure: NirvResult<String> = Err(NirvError::Internal("test error".to_string()));
176        
177        assert!(success.is_ok());
178        assert!(failure.is_err());
179        
180        match failure {
181            Err(NirvError::Internal(msg)) => assert_eq!(msg, "test error"),
182            _ => panic!("Expected Internal error"),
183        }
184    }
185}