ansible/errors.rs
1//! Comprehensive error handling for Ansible operations.
2//!
3//! This module provides detailed error types for different failure modes
4//! that can occur when working with Ansible commands and operations.
5
6use thiserror::Error;
7
8/// Comprehensive error types for Ansible operations.
9///
10/// The `AnsibleError` enum provides detailed error information for different
11/// types of failures that can occur when executing Ansible commands, managing
12/// configurations, or working with inventories.
13///
14/// # Examples
15///
16/// ## Error Handling
17///
18/// ```rust,no_run
19/// use ansible::{Ansible, AnsibleError};
20///
21/// let result = Ansible::default().ping();
22/// match result {
23/// Ok(output) => println!("Success: {}", output),
24/// Err(AnsibleError::CommandFailed { message, exit_code, stdout, stderr }) => {
25/// eprintln!("Command failed: {}", message);
26/// if let Some(code) = exit_code {
27/// eprintln!("Exit code: {}", code);
28/// }
29/// if let Some(stderr) = stderr {
30/// eprintln!("Error output: {}", stderr);
31/// }
32/// }
33/// Err(AnsibleError::UnsupportedPlatform(msg)) => {
34/// eprintln!("Platform not supported: {}", msg);
35/// }
36/// Err(e) => eprintln!("Other error: {}", e),
37/// }
38/// ```
39///
40/// ## Error Construction
41///
42/// ```rust
43/// use ansible::AnsibleError;
44///
45/// // Create specific error types
46/// let cmd_error = AnsibleError::command_failed(
47/// "ansible ping failed",
48/// Some(1),
49/// Some("output".to_string()),
50/// Some("error".to_string())
51/// );
52///
53/// let platform_error = AnsibleError::unsupported_platform("Windows not supported");
54/// ```
55#[derive(Error, Debug)]
56pub enum AnsibleError {
57 /// I/O operation failed
58 #[error("I/O operation failed: {0}")]
59 Io(#[from] std::io::Error),
60
61 /// Ansible command execution failed
62 #[error("Ansible command execution failed: {message}")]
63 CommandFailed {
64 message: String,
65 exit_code: Option<i32>,
66 stdout: Option<String>,
67 stderr: Option<String>,
68 },
69
70 /// Invalid module configuration
71 #[error("Invalid module configuration: {0}")]
72 InvalidModule(String),
73
74 /// Invalid inventory configuration
75 #[error("Invalid inventory configuration: {0}")]
76 InvalidInventory(String),
77
78 /// Playbook parsing or execution error
79 #[error("Playbook error: {0}")]
80 PlaybookError(String),
81
82 /// Environment variable error
83 #[error("Environment variable error: {0}")]
84 EnvironmentError(String),
85
86 /// Configuration error
87 #[error("Configuration error: {0}")]
88 ConfigError(String),
89
90 /// Unsupported platform error
91 #[error("Unsupported platform: {0}")]
92 UnsupportedPlatform(String),
93
94 /// Command not found error
95 #[error("Command not found: {0}")]
96 CommandNotFound(String),
97
98 /// System requirement not met
99 #[error("System requirement not met: {0}")]
100 SystemRequirement(String),
101
102 /// Unknown error
103 #[error("Unknown error occurred")]
104 Unknown,
105}
106
107impl AnsibleError {
108 /// Create a command failed error with detailed information
109 pub fn command_failed(
110 message: impl Into<String>,
111 exit_code: Option<i32>,
112 stdout: Option<String>,
113 stderr: Option<String>,
114 ) -> Self {
115 Self::CommandFailed {
116 message: message.into(),
117 exit_code,
118 stdout,
119 stderr,
120 }
121 }
122
123 /// Create an invalid module error
124 pub fn invalid_module(message: impl Into<String>) -> Self {
125 Self::InvalidModule(message.into())
126 }
127
128 /// Create an invalid inventory error
129 pub fn invalid_inventory(message: impl Into<String>) -> Self {
130 Self::InvalidInventory(message.into())
131 }
132
133 /// Create a playbook error
134 pub fn playbook_error(message: impl Into<String>) -> Self {
135 Self::PlaybookError(message.into())
136 }
137
138 /// Create an environment error
139 pub fn environment_error(message: impl Into<String>) -> Self {
140 Self::EnvironmentError(message.into())
141 }
142
143 /// Create a configuration error
144 pub fn config_error(message: impl Into<String>) -> Self {
145 Self::ConfigError(message.into())
146 }
147
148 /// Create an unsupported platform error
149 pub fn unsupported_platform(message: impl Into<String>) -> Self {
150 Self::UnsupportedPlatform(message.into())
151 }
152
153 /// Create a command not found error
154 pub fn command_not_found(message: impl Into<String>) -> Self {
155 Self::CommandNotFound(message.into())
156 }
157
158 /// Create a system requirement error
159 pub fn system_requirement(message: impl Into<String>) -> Self {
160 Self::SystemRequirement(message.into())
161 }
162
163 /// Create a parsing failed error
164 pub fn parsing_failed(message: impl Into<String>) -> Self {
165 Self::ConfigError(message.into())
166 }
167
168 /// Create an IO error
169 pub fn io_error(message: impl Into<String>) -> Self {
170 Self::ConfigError(message.into())
171 }
172}
173
174/// Type alias for Results with AnsibleError
175pub type Result<T> = std::result::Result<T, AnsibleError>;