1use thiserror::Error;
4
5#[derive(Error, Debug)]
7pub enum AimdsError {
8 #[error("Detection error: {0}")]
9 Detection(String),
10
11 #[error("Analysis error: {0}")]
12 Analysis(String),
13
14 #[error("Response error: {0}")]
15 Response(String),
16
17 #[error("Configuration error: {0}")]
18 Configuration(String),
19
20 #[error("IO error: {0}")]
21 Io(#[from] std::io::Error),
22
23 #[error("Serialization error: {0}")]
24 Serialization(#[from] serde_json::Error),
25
26 #[error("Validation error: {0}")]
27 Validation(String),
28
29 #[error("Timeout error: operation timed out after {0}ms")]
30 Timeout(u64),
31
32 #[error("External service error: {service}: {message}")]
33 ExternalService { service: String, message: String },
34
35 #[error("Internal error: {0}")]
36 Internal(String),
37
38 #[error(transparent)]
39 Other(#[from] anyhow::Error),
40}
41
42pub type Result<T> = std::result::Result<T, AimdsError>;
44
45impl AimdsError {
46 pub fn is_retryable(&self) -> bool {
48 matches!(
49 self,
50 AimdsError::Timeout(_) | AimdsError::ExternalService { .. }
51 )
52 }
53
54 pub fn severity(&self) -> ErrorSeverity {
56 match self {
57 AimdsError::Internal(_) => ErrorSeverity::Critical,
58 AimdsError::Configuration(_) => ErrorSeverity::Critical,
59 AimdsError::Detection(_) | AimdsError::Analysis(_) => ErrorSeverity::High,
60 AimdsError::Timeout(_) | AimdsError::ExternalService { .. } => ErrorSeverity::Medium,
61 _ => ErrorSeverity::Low,
62 }
63 }
64}
65
66#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
68pub enum ErrorSeverity {
69 Low,
70 Medium,
71 High,
72 Critical,
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn test_error_retryable() {
81 let timeout_err = AimdsError::Timeout(5000);
82 assert!(timeout_err.is_retryable());
83
84 let config_err = AimdsError::Configuration("Invalid config".to_string());
85 assert!(!config_err.is_retryable());
86 }
87
88 #[test]
89 fn test_error_severity() {
90 let internal_err = AimdsError::Internal("Critical failure".to_string());
91 assert_eq!(internal_err.severity(), ErrorSeverity::Critical);
92
93 let timeout_err = AimdsError::Timeout(1000);
94 assert_eq!(timeout_err.severity(), ErrorSeverity::Medium);
95 }
96}