//! Configuration error types and result handling. //! //! This module defines comprehensive error types for configuration management //! operations, including database errors, vault integration failures, parsing //! errors, and validation issues. Uses thiserror for ergonomic error handling. use thiserror::Error; /// Comprehensive error type for configuration management operations. /// /// Covers all possible error conditions that can occur during configuration /// loading, validation, and management operations. Each variant provides /// specific context about the failure to aid in debugging and error handling. #[derive(Error, Debug)] #[allow(clippy::module_name_repetitions)] pub enum ConfigError { /// Database operation failed (connection, query, or transaction error) #[error("Database error: {0}")] Database(#[from] sqlx::Error), /// HashiCorp Vault integration error (authentication, secret retrieval, etc.) #[error("Vault error: {0}")] Vault(String), /// Configuration parsing error (invalid TOML, JSON, or environment variables) #[error("Parse error: {0}")] Parse(String), /// Requested configuration key or resource was not found #[error("Not found: {0}")] NotFound(String), /// Configuration validation failed (invalid values, missing required fields) #[error("Invalid configuration: {0}")] Invalid(String), } /// Result type alias for configuration operations. /// /// Provides a convenient Result type that uses ConfigError as the error type. /// /// Used throughout the configuration system for consistent error handling. pub type ConfigResult = Result; #[cfg(test)] mod tests { use super::*; #[test] fn test_vault_error_display() { let error = ConfigError::Vault("Connection failed".to_owned()); assert_eq!(format!("{}", error), "Vault error: Connection failed"); } #[test] fn test_parse_error_display() { let error = ConfigError::Parse("Invalid JSON".to_owned()); assert_eq!(format!("{}", error), "Parse error: Invalid JSON"); } #[test] fn test_not_found_error_display() { let error = ConfigError::NotFound("config_key".to_owned()); assert_eq!(format!("{}", error), "Not found: config_key"); } #[test] fn test_invalid_error_display() { let error = ConfigError::Invalid("Missing required field".to_owned()); assert_eq!( format!("{}", error), "Invalid configuration: Missing required field" ); } #[test] fn test_error_debug_format() { let error = ConfigError::Vault("Test error".to_owned()); let debug_output = format!("{:?}", error); assert!(debug_output.contains("Vault")); assert!(debug_output.contains("Test error")); } #[test] fn test_config_result_ok() { let result: ConfigResult = Ok(42); assert!(result.is_ok()); match result { Ok(value) => assert_eq!(value, 42), Err(_) => panic!("Expected Ok value"), } } #[test] fn test_config_result_err() { let result: ConfigResult = Err(ConfigError::NotFound("test".to_owned())); assert!(result.is_err()); } #[test] fn test_error_type_matching() { let error = ConfigError::Parse("syntax error".to_owned()); match error { ConfigError::Parse(msg) => assert_eq!(msg, "syntax error"), _ => panic!("Expected Parse error"), } } #[test] fn test_vault_error_creation() { let error = ConfigError::Vault("Token expired".to_owned()); if let ConfigError::Vault(msg) = error { assert_eq!(msg, "Token expired"); } else { panic!("Expected Vault error"); } } }