mockforge_core/
error.rs

1//! Error types for MockForge Core
2
3/// Result type alias for MockForge operations
4pub type Result<T> = std::result::Result<T, Error>;
5
6/// Core error types for MockForge
7#[derive(Debug, thiserror::Error)]
8pub enum Error {
9    #[error("Validation error: {message}")]
10    Validation { message: String },
11
12    #[error("Routing error: {message}")]
13    Routing { message: String },
14
15    #[error("Proxy error: {message}")]
16    Proxy { message: String },
17
18    #[error("Latency simulation error: {message}")]
19    Latency { message: String },
20
21    #[error("Configuration error: {message}")]
22    Config { message: String },
23
24    #[error("Protocol not found: {message}")]
25    ProtocolNotFound { message: String },
26
27    #[error("Protocol disabled: {message}")]
28    ProtocolDisabled { message: String },
29
30    #[error("Protocol handler in use: {message}")]
31    ProtocolHandlerInUse { message: String },
32
33    #[error("Protocol validation error: {message}")]
34    ProtocolValidationError { protocol: String, message: String },
35
36    #[error("IO error: {0}")]
37    Io(#[from] std::io::Error),
38
39    #[error("JSON error: {0}")]
40    Json(#[from] serde_json::Error),
41
42    #[error("YAML error: {0}")]
43    Yaml(#[from] serde_yaml::Error),
44
45    #[error("HTTP error: {0}")]
46    Http(#[from] reqwest::Error),
47
48    #[error("URL parse error: {0}")]
49    UrlParse(#[from] url::ParseError),
50
51    #[error("Regex error: {0}")]
52    Regex(#[from] regex::Error),
53
54    #[error("Generic error: {0}")]
55    Generic(String),
56
57    #[error("Encryption error: {0}")]
58    Encryption(#[from] crate::encryption::EncryptionError),
59
60    #[error("JavaScript error: {0}")]
61    JavaScript(#[from] rquickjs::Error),
62}
63
64impl From<String> for Error {
65    fn from(message: String) -> Self {
66        Self::Generic(message)
67    }
68}
69
70impl Error {
71    /// Create a validation error
72    pub fn validation<S: Into<String>>(message: S) -> Self {
73        Self::Validation {
74            message: message.into(),
75        }
76    }
77
78    /// Create a routing error
79    pub fn routing<S: Into<String>>(message: S) -> Self {
80        Self::Routing {
81            message: message.into(),
82        }
83    }
84
85    /// Create a proxy error
86    pub fn proxy<S: Into<String>>(message: S) -> Self {
87        Self::Proxy {
88            message: message.into(),
89        }
90    }
91
92    /// Create a latency error
93    pub fn latency<S: Into<String>>(message: S) -> Self {
94        Self::Latency {
95            message: message.into(),
96        }
97    }
98
99    /// Create a config error
100    pub fn config<S: Into<String>>(message: S) -> Self {
101        Self::Config {
102            message: message.into(),
103        }
104    }
105
106    /// Create a protocol not found error
107    pub fn protocol_not_found<S: Into<String>>(message: S) -> Self {
108        Self::ProtocolNotFound {
109            message: message.into(),
110        }
111    }
112
113    /// Create a protocol disabled error
114    pub fn protocol_disabled<S: Into<String>>(message: S) -> Self {
115        Self::ProtocolDisabled {
116            message: message.into(),
117        }
118    }
119
120    /// Create a protocol handler in use error
121    pub fn protocol_handler_in_use<S: Into<String>>(message: S) -> Self {
122        Self::ProtocolHandlerInUse {
123            message: message.into(),
124        }
125    }
126
127    /// Create a protocol validation error
128    pub fn protocol_validation_error<S: Into<String>>(protocol: S, message: S) -> Self {
129        Self::ProtocolValidationError {
130            protocol: protocol.into(),
131            message: message.into(),
132        }
133    }
134
135    /// Create a generic error
136    pub fn generic<S: Into<String>>(message: S) -> Self {
137        Self::Generic(message.into())
138    }
139}
140
141#[cfg(test)]
142mod tests {
143    use super::*;
144
145    #[test]
146    fn test_validation_error() {
147        let err = Error::validation("test validation");
148        assert!(err.to_string().contains("Validation error"));
149        assert!(err.to_string().contains("test validation"));
150    }
151
152    #[test]
153    fn test_routing_error() {
154        let err = Error::routing("test routing");
155        assert!(err.to_string().contains("Routing error"));
156        assert!(err.to_string().contains("test routing"));
157    }
158
159    #[test]
160    fn test_proxy_error() {
161        let err = Error::proxy("test proxy");
162        assert!(err.to_string().contains("Proxy error"));
163        assert!(err.to_string().contains("test proxy"));
164    }
165
166    #[test]
167    fn test_latency_error() {
168        let err = Error::latency("test latency");
169        assert!(err.to_string().contains("Latency simulation error"));
170        assert!(err.to_string().contains("test latency"));
171    }
172
173    #[test]
174    fn test_config_error() {
175        let err = Error::config("test config");
176        assert!(err.to_string().contains("Configuration error"));
177        assert!(err.to_string().contains("test config"));
178    }
179
180    #[test]
181    fn test_generic_error() {
182        let err = Error::generic("test generic");
183        assert!(err.to_string().contains("Generic error"));
184        assert!(err.to_string().contains("test generic"));
185    }
186
187    #[test]
188    fn test_from_string() {
189        let err: Error = "test message".to_string().into();
190        assert!(matches!(err, Error::Generic(_)));
191        assert!(err.to_string().contains("test message"));
192    }
193
194    #[test]
195    fn test_json_error_conversion() {
196        let json_err = serde_json::from_str::<serde_json::Value>("invalid json");
197        assert!(json_err.is_err());
198        let err: Error = json_err.unwrap_err().into();
199        assert!(matches!(err, Error::Json(_)));
200    }
201
202    #[test]
203    fn test_url_parse_error_conversion() {
204        let url_err = url::Url::parse("not a url");
205        assert!(url_err.is_err());
206        let err: Error = url_err.unwrap_err().into();
207        assert!(matches!(err, Error::UrlParse(_)));
208    }
209
210    #[test]
211    #[allow(clippy::invalid_regex)]
212    fn test_regex_error_conversion() {
213        let regex_err = regex::Regex::new("[invalid(");
214        assert!(regex_err.is_err());
215        let err: Error = regex_err.unwrap_err().into();
216        assert!(matches!(err, Error::Regex(_)));
217    }
218
219    #[test]
220    fn test_error_display() {
221        let errors = vec![
222            (Error::validation("msg"), "Validation error: msg"),
223            (Error::routing("msg"), "Routing error: msg"),
224            (Error::proxy("msg"), "Proxy error: msg"),
225            (Error::latency("msg"), "Latency simulation error: msg"),
226            (Error::config("msg"), "Configuration error: msg"),
227            (Error::generic("msg"), "Generic error: msg"),
228        ];
229
230        for (err, expected) in errors {
231            assert_eq!(err.to_string(), expected);
232        }
233    }
234}