aws_assume_role/error/
mod.rs

1use std::error::Error;
2use std::fmt;
3
4#[derive(Debug)]
5#[allow(clippy::enum_variant_names)]
6pub enum AppError {
7    AwsError(String),
8    ConfigError(String),
9    CliError(String),
10    IoError(std::io::Error),
11}
12
13impl fmt::Display for AppError {
14    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15        match self {
16            AppError::AwsError(msg) => write!(f, "{}", msg),
17            AppError::ConfigError(msg) => write!(f, "{}", msg),
18            AppError::CliError(msg) => write!(f, "{}", msg),
19            AppError::IoError(e) => write!(f, "{}", e),
20        }
21    }
22}
23
24impl Error for AppError {
25    fn source(&self) -> Option<&(dyn Error + 'static)> {
26        match self {
27            AppError::IoError(e) => Some(e),
28            _ => None,
29        }
30    }
31}
32
33impl From<std::io::Error> for AppError {
34    fn from(err: std::io::Error) -> Self {
35        AppError::IoError(err)
36    }
37}
38
39pub type AppResult<T> = Result<T, AppError>;
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44
45    #[test]
46    fn test_cli_error_creation() {
47        let error = AppError::CliError("Test CLI error".to_string());
48        assert!(matches!(error, AppError::CliError(_)));
49
50        let error_string = error.to_string();
51        assert!(error_string.contains("Test CLI error"));
52    }
53
54    #[test]
55    fn test_aws_error_creation() {
56        let error = AppError::AwsError("Test AWS error".to_string());
57        assert!(matches!(error, AppError::AwsError(_)));
58
59        let error_string = error.to_string();
60        assert!(error_string.contains("Test AWS error"));
61    }
62
63    #[test]
64    fn test_config_error_creation() {
65        let error = AppError::ConfigError("Test config error".to_string());
66        assert!(matches!(error, AppError::ConfigError(_)));
67
68        let error_string = error.to_string();
69        assert!(error_string.contains("Test config error"));
70    }
71
72    #[test]
73    fn test_io_error_creation() {
74        let io_error = std::io::Error::new(std::io::ErrorKind::NotFound, "File not found");
75        let error = AppError::IoError(io_error);
76        assert!(matches!(error, AppError::IoError(_)));
77
78        let error_string = error.to_string();
79        assert!(error_string.contains("File not found"));
80    }
81
82    #[test]
83    fn test_config_error_with_json() {
84        let json_error = serde_json::from_str::<serde_json::Value>("invalid json").unwrap_err();
85        let error = AppError::ConfigError(format!("JSON parsing error: {}", json_error));
86        assert!(matches!(error, AppError::ConfigError(_)));
87    }
88
89    #[test]
90    fn test_error_from_io() {
91        let io_error =
92            std::io::Error::new(std::io::ErrorKind::PermissionDenied, "Permission denied");
93        let app_error: AppError = io_error.into();
94        assert!(matches!(app_error, AppError::IoError(_)));
95    }
96
97    #[test]
98    fn test_error_conversion() {
99        let json_error = serde_json::from_str::<serde_json::Value>("invalid json").unwrap_err();
100        let error_msg = format!("JSON parsing error: {}", json_error);
101        let app_error = AppError::ConfigError(error_msg);
102        assert!(matches!(app_error, AppError::ConfigError(_)));
103    }
104
105    #[test]
106    fn test_error_display() {
107        let cli_error = AppError::CliError("CLI error message".to_string());
108        let display = format!("{}", cli_error);
109        assert_eq!(display, "CLI error message");
110
111        let aws_error = AppError::AwsError("AWS error message".to_string());
112        let display = format!("{}", aws_error);
113        assert_eq!(display, "AWS error message");
114
115        let config_error = AppError::ConfigError("Config error message".to_string());
116        let display = format!("{}", config_error);
117        assert_eq!(display, "Config error message");
118    }
119
120    #[test]
121    fn test_error_debug() {
122        let error = AppError::CliError("Debug test".to_string());
123        let debug_output = format!("{:?}", error);
124        assert!(debug_output.contains("CliError"));
125        assert!(debug_output.contains("Debug test"));
126    }
127
128    #[test]
129    fn test_app_result_ok() {
130        let success_value = "Success".to_string();
131        let result: AppResult<String> = Ok(success_value.clone());
132        assert!(result.is_ok());
133        if let Ok(value) = result {
134            assert_eq!(value, success_value);
135        }
136    }
137
138    #[test]
139    fn test_app_result_err() {
140        let result: AppResult<String> = Err(AppError::CliError("Error".to_string()));
141        assert!(result.is_err());
142
143        match result {
144            Err(AppError::CliError(msg)) => assert_eq!(msg, "Error"),
145            _ => panic!("Expected CliError"),
146        }
147    }
148
149    #[test]
150    fn test_error_chain() {
151        let io_error = std::io::Error::new(std::io::ErrorKind::NotFound, "File not found");
152        let app_error = AppError::IoError(io_error);
153
154        // Test that we can access the source error
155        let error_msg = format!("{}", app_error);
156        assert!(error_msg.contains("File not found"));
157    }
158
159    #[test]
160    fn test_multiple_error_types() {
161        let errors = vec![
162            AppError::CliError("CLI".to_string()),
163            AppError::AwsError("AWS".to_string()),
164            AppError::ConfigError("Config".to_string()),
165        ];
166
167        for error in errors {
168            let _display = format!("{}", error);
169            let _debug = format!("{:?}", error);
170            // Just ensure they don't panic
171        }
172    }
173}