Skip to content

Commit e725f82

Browse files
committed
refactor: [#162] rename CreateSubcommandError to CreateEnvironmentCommandError
- Update error type name throughout codebase for better semantic clarity - Rename enum definition and all impl blocks in errors.rs - Update module re-exports in environment/mod.rs and create/mod.rs - Fix function signatures and error constructors in router.rs, handler.rs, template handler - Update config_loader.rs with new error types and test cases - Fix integration tests and environment-specific tests - Update presentation module export in mod.rs - All tests passing (1188 passed, 0 failed) The new name better reflects that this error type is specifically for environment creation commands, improving code clarity and maintainability.
1 parent 55eec41 commit e725f82

File tree

11 files changed

+76
-72
lines changed

11 files changed

+76
-72
lines changed

src/presentation/controllers/create/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,4 @@ mod tests;
4646

4747
// Re-export commonly used types for convenience
4848
pub use router::route_command;
49-
pub use subcommands::environment::{ConfigFormat, ConfigLoader, CreateSubcommandError};
49+
pub use subcommands::environment::{ConfigFormat, ConfigLoader, CreateEnvironmentCommandError};

src/presentation/controllers/create/router.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::presentation::dispatch::ExecutionContext;
99
use crate::presentation::input::cli::commands::CreateAction;
1010

1111
use super::subcommands;
12-
use super::subcommands::environment::CreateSubcommandError;
12+
use super::subcommands::environment::CreateEnvironmentCommandError;
1313

1414
/// Route the create command to its appropriate subcommand
1515
///
@@ -23,7 +23,7 @@ use super::subcommands::environment::CreateSubcommandError;
2323
///
2424
/// # Returns
2525
///
26-
/// Returns `Ok(())` on success, or a `CreateSubcommandError` on failure.
26+
/// Returns `Ok(())` on success, or a `CreateEnvironmentCommandError` on failure.
2727
///
2828
/// # Errors
2929
///
@@ -33,7 +33,7 @@ pub fn route_command(
3333
action: CreateAction,
3434
working_dir: &Path,
3535
context: &ExecutionContext,
36-
) -> Result<(), CreateSubcommandError> {
36+
) -> Result<(), CreateEnvironmentCommandError> {
3737
match action {
3838
CreateAction::Environment { env_file } => {
3939
subcommands::handle_environment_creation(&env_file, working_dir, context)

src/presentation/controllers/create/subcommands/environment/config_loader.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use figment::{
1313

1414
use crate::application::command_handlers::create::config::EnvironmentCreationConfig;
1515

16-
use super::errors::{ConfigFormat, CreateSubcommandError};
16+
use super::errors::{ConfigFormat, CreateEnvironmentCommandError};
1717

1818
/// Configuration loader using Figment for JSON file parsing
1919
///
@@ -41,7 +41,7 @@ impl ConfigLoader {
4141
/// # Returns
4242
///
4343
/// * `Ok(EnvironmentCreationConfig)` - Successfully loaded and validated configuration
44-
/// * `Err(CreateSubcommandError)` - File not found, parsing failed, or validation failed
44+
/// * `Err(CreateEnvironmentCommandError)` - File not found, parsing failed, or validation failed
4545
///
4646
/// # Errors
4747
///
@@ -67,10 +67,10 @@ impl ConfigLoader {
6767
pub fn load_from_file(
6868
&self,
6969
config_path: &Path,
70-
) -> Result<EnvironmentCreationConfig, CreateSubcommandError> {
70+
) -> Result<EnvironmentCreationConfig, CreateEnvironmentCommandError> {
7171
// Step 1: Verify file exists
7272
if !config_path.exists() {
73-
return Err(CreateSubcommandError::ConfigFileNotFound {
73+
return Err(CreateEnvironmentCommandError::ConfigFileNotFound {
7474
path: config_path.to_path_buf(),
7575
});
7676
}
@@ -80,18 +80,20 @@ impl ConfigLoader {
8080
let config: EnvironmentCreationConfig = Figment::new()
8181
.merge(Json::file(config_path))
8282
.extract()
83-
.map_err(|source| CreateSubcommandError::ConfigParsingFailed {
84-
path: config_path.to_path_buf(),
85-
format: ConfigFormat::Json,
86-
source: Box::new(source),
87-
})?;
83+
.map_err(
84+
|source| CreateEnvironmentCommandError::ConfigParsingFailed {
85+
path: config_path.to_path_buf(),
86+
format: ConfigFormat::Json,
87+
source: Box::new(source),
88+
},
89+
)?;
8890

8991
// Step 3: Validate using domain rules
9092
// This converts string-based config to domain types and validates
9193
config
9294
.clone()
9395
.to_environment_params()
94-
.map_err(|source| CreateSubcommandError::ConfigValidationFailed { source })?;
96+
.map_err(|source| CreateEnvironmentCommandError::ConfigValidationFailed { source })?;
9597

9698
Ok(config)
9799
}
@@ -145,7 +147,7 @@ mod tests {
145147

146148
assert!(result.is_err());
147149
match result.unwrap_err() {
148-
CreateSubcommandError::ConfigFileNotFound { path } => {
150+
CreateEnvironmentCommandError::ConfigFileNotFound { path } => {
149151
assert_eq!(path, config_path);
150152
}
151153
_ => panic!("Expected ConfigFileNotFound error"),
@@ -165,7 +167,7 @@ mod tests {
165167

166168
assert!(result.is_err());
167169
match result.unwrap_err() {
168-
CreateSubcommandError::ConfigParsingFailed { path, format, .. } => {
170+
CreateEnvironmentCommandError::ConfigParsingFailed { path, format, .. } => {
169171
assert_eq!(path, config_path);
170172
assert!(matches!(format, ConfigFormat::Json));
171173
}
@@ -217,7 +219,7 @@ mod tests {
217219

218220
assert!(result.is_err());
219221
match result.unwrap_err() {
220-
CreateSubcommandError::ConfigValidationFailed { .. } => {
222+
CreateEnvironmentCommandError::ConfigValidationFailed { .. } => {
221223
// Expected - validation should catch invalid environment name
222224
}
223225
other => panic!("Expected ConfigValidationFailed, got: {other:?}"),
@@ -246,7 +248,7 @@ mod tests {
246248

247249
assert!(result.is_err());
248250
match result.unwrap_err() {
249-
CreateSubcommandError::ConfigValidationFailed { .. } => {
251+
CreateEnvironmentCommandError::ConfigValidationFailed { .. } => {
250252
// Expected - validation should catch missing SSH keys
251253
}
252254
other => panic!("Expected ConfigValidationFailed, got: {other:?}"),

src/presentation/controllers/create/subcommands/environment/errors.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ impl std::fmt::Display for ConfigFormat {
2525
}
2626
}
2727

28-
/// Errors that can occur during create subcommand execution
28+
/// Errors that can occur during create environment command execution
2929
///
3030
/// These errors represent failures in the CLI presentation layer when
31-
/// handling the create command. They provide structured context for
31+
/// handling the create environment command. They provide structured context for
3232
/// troubleshooting and user feedback.
3333
#[derive(Debug, Error)]
34-
pub enum CreateSubcommandError {
34+
pub enum CreateEnvironmentCommandError {
3535
// ===== Configuration File Errors =====
3636
/// Configuration file not found
3737
///
@@ -134,13 +134,13 @@ Tip: This is a critical bug - please report it with full logs using --log-output
134134
// ERROR CONVERSIONS
135135
// ============================================================================
136136

137-
impl From<ProgressReporterError> for CreateSubcommandError {
137+
impl From<ProgressReporterError> for CreateEnvironmentCommandError {
138138
fn from(source: ProgressReporterError) -> Self {
139139
Self::ProgressReportingFailed { source }
140140
}
141141
}
142142

143-
impl CreateSubcommandError {
143+
impl CreateEnvironmentCommandError {
144144
/// Provides detailed troubleshooting guidance for this error
145145
///
146146
/// Returns context-specific help text that guides users toward resolving
@@ -150,10 +150,10 @@ impl CreateSubcommandError {
150150
/// # Examples
151151
///
152152
/// ```rust
153-
/// use torrust_tracker_deployer_lib::presentation::controllers::create::CreateSubcommandError;
153+
/// use torrust_tracker_deployer_lib::presentation::controllers::create::CreateEnvironmentCommandError;
154154
/// use std::path::PathBuf;
155155
///
156-
/// let error = CreateSubcommandError::ConfigFileNotFound {
156+
/// let error = CreateEnvironmentCommandError::ConfigFileNotFound {
157157
/// path: PathBuf::from("config.json"),
158158
/// };
159159
///
@@ -280,7 +280,7 @@ mod tests {
280280

281281
#[test]
282282
fn it_should_provide_help_for_config_file_not_found() {
283-
let error = CreateSubcommandError::ConfigFileNotFound {
283+
let error = CreateEnvironmentCommandError::ConfigFileNotFound {
284284
path: PathBuf::from("missing.json"),
285285
};
286286

@@ -293,7 +293,7 @@ mod tests {
293293
#[test]
294294
fn it_should_provide_help_for_json_parsing_failed() {
295295
let source = std::io::Error::new(std::io::ErrorKind::InvalidData, "invalid json");
296-
let error = CreateSubcommandError::ConfigParsingFailed {
296+
let error = CreateEnvironmentCommandError::ConfigParsingFailed {
297297
path: PathBuf::from("config.json"),
298298
format: ConfigFormat::Json,
299299
source: Box::new(source),
@@ -307,7 +307,7 @@ mod tests {
307307

308308
#[test]
309309
fn it_should_display_config_file_path_in_error() {
310-
let error = CreateSubcommandError::ConfigFileNotFound {
310+
let error = CreateEnvironmentCommandError::ConfigFileNotFound {
311311
path: PathBuf::from("/path/to/config.json"),
312312
};
313313

@@ -319,7 +319,7 @@ mod tests {
319319
#[test]
320320
fn it_should_display_format_in_parsing_error() {
321321
let source = std::io::Error::new(std::io::ErrorKind::InvalidData, "test");
322-
let error = CreateSubcommandError::ConfigParsingFailed {
322+
let error = CreateEnvironmentCommandError::ConfigParsingFailed {
323323
path: PathBuf::from("config.json"),
324324
format: ConfigFormat::Json,
325325
source: Box::new(source),
@@ -336,16 +336,16 @@ mod tests {
336336
use crate::domain::EnvironmentNameError;
337337
use crate::presentation::progress::ProgressReporterError;
338338

339-
let errors: Vec<CreateSubcommandError> = vec![
340-
CreateSubcommandError::ConfigFileNotFound {
339+
let errors: Vec<CreateEnvironmentCommandError> = vec![
340+
CreateEnvironmentCommandError::ConfigFileNotFound {
341341
path: PathBuf::from("test.json"),
342342
},
343-
CreateSubcommandError::ConfigParsingFailed {
343+
CreateEnvironmentCommandError::ConfigParsingFailed {
344344
path: PathBuf::from("test.json"),
345345
format: ConfigFormat::Json,
346346
source: Box::new(std::io::Error::new(std::io::ErrorKind::InvalidData, "test")),
347347
},
348-
CreateSubcommandError::ConfigValidationFailed {
348+
CreateEnvironmentCommandError::ConfigValidationFailed {
349349
source: CreateConfigError::InvalidEnvironmentName(
350350
EnvironmentNameError::InvalidFormat {
351351
attempted_name: "test".to_string(),
@@ -354,8 +354,8 @@ mod tests {
354354
},
355355
),
356356
},
357-
CreateSubcommandError::UserOutputLockFailed,
358-
CreateSubcommandError::ProgressReportingFailed {
357+
CreateEnvironmentCommandError::UserOutputLockFailed,
358+
CreateEnvironmentCommandError::ProgressReportingFailed {
359359
source: ProgressReporterError::UserOutputMutexPoisoned,
360360
},
361361
];

src/presentation/controllers/create/subcommands/environment/handler.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::presentation::user_output::UserOutput;
1717
use crate::shared::clock::SystemClock;
1818

1919
use super::config_loader::ConfigLoader;
20-
use super::errors::CreateSubcommandError;
20+
use super::errors::CreateEnvironmentCommandError;
2121

2222
/// Handle environment creation from configuration file
2323
///
@@ -39,7 +39,7 @@ use super::errors::CreateSubcommandError;
3939
///
4040
/// # Returns
4141
///
42-
/// Returns `Ok(())` on success, or a `CreateSubcommandError` if any step fails.
42+
/// Returns `Ok(())` on success, or a `CreateEnvironmentCommandError` if any step fails.
4343
///
4444
/// # Errors
4545
///
@@ -53,7 +53,7 @@ pub fn handle_environment_creation(
5353
env_file: &Path,
5454
working_dir: &Path,
5555
context: &ExecutionContext,
56-
) -> Result<(), CreateSubcommandError> {
56+
) -> Result<(), CreateEnvironmentCommandError> {
5757
// Create progress reporter for 3 main steps
5858
let mut progress = ProgressReporter::new(context.user_output().clone(), 3);
5959

@@ -122,12 +122,12 @@ pub fn handle_environment_creation(
122122
pub(crate) fn load_configuration(
123123
progress: &mut ProgressReporter,
124124
env_file: &Path,
125-
) -> Result<EnvironmentCreationConfig, CreateSubcommandError> {
125+
) -> Result<EnvironmentCreationConfig, CreateEnvironmentCommandError> {
126126
let user_output = progress.output();
127127

128128
user_output
129129
.lock()
130-
.map_err(|_| CreateSubcommandError::UserOutputLockFailed)?
130+
.map_err(|_| CreateEnvironmentCommandError::UserOutputLockFailed)?
131131
.progress(&format!(
132132
"Loading configuration from '{}'...",
133133
env_file.display()
@@ -137,7 +137,7 @@ pub(crate) fn load_configuration(
137137

138138
loader
139139
.load_from_file(env_file)
140-
.inspect_err(|err: &CreateSubcommandError| {
140+
.inspect_err(|err: &CreateEnvironmentCommandError| {
141141
// Attempt to log error, but don't fail if mutex is poisoned
142142
if let Ok(mut output) = user_output.lock() {
143143
output.error(&err.to_string());
@@ -168,25 +168,25 @@ pub(crate) fn execute_create_command(
168168
progress: &mut ProgressReporter,
169169
command_handler: &CreateCommandHandler,
170170
config: EnvironmentCreationConfig,
171-
) -> Result<Environment, CreateSubcommandError> {
171+
) -> Result<Environment, CreateEnvironmentCommandError> {
172172
let user_output = progress.output();
173173

174174
user_output
175175
.lock()
176-
.map_err(|_| CreateSubcommandError::UserOutputLockFailed)?
176+
.map_err(|_| CreateEnvironmentCommandError::UserOutputLockFailed)?
177177
.progress(&format!(
178178
"Creating environment '{}'...",
179179
config.environment.name
180180
));
181181

182182
user_output
183183
.lock()
184-
.map_err(|_| CreateSubcommandError::UserOutputLockFailed)?
184+
.map_err(|_| CreateEnvironmentCommandError::UserOutputLockFailed)?
185185
.progress("Validating configuration and creating environment...");
186186

187187
#[allow(clippy::manual_inspect)]
188188
command_handler.execute(config).map_err(|source| {
189-
let error = CreateSubcommandError::CommandFailed { source };
189+
let error = CreateEnvironmentCommandError::CommandFailed { source };
190190
// Attempt to log error, but don't fail if mutex is poisoned
191191
if let Ok(mut output) = user_output.lock() {
192192
output.error(&error.to_string());
@@ -210,7 +210,7 @@ pub(crate) fn execute_create_command(
210210
///
211211
/// # Returns
212212
///
213-
/// Returns `Ok(())` on success, or `CreateSubcommandError::UserOutputLockFailed`
213+
/// Returns `Ok(())` on success, or `CreateEnvironmentCommandError::UserOutputLockFailed`
214214
/// if the `UserOutput` mutex is poisoned.
215215
///
216216
/// # Errors
@@ -220,10 +220,10 @@ pub(crate) fn execute_create_command(
220220
pub(crate) fn display_creation_results(
221221
user_output: &Arc<Mutex<UserOutput>>,
222222
environment: &Environment,
223-
) -> Result<(), CreateSubcommandError> {
223+
) -> Result<(), CreateEnvironmentCommandError> {
224224
let mut output = user_output
225225
.lock()
226-
.map_err(|_| CreateSubcommandError::UserOutputLockFailed)?;
226+
.map_err(|_| CreateEnvironmentCommandError::UserOutputLockFailed)?;
227227

228228
output.success(&format!(
229229
"Environment '{}' created successfully",

src/presentation/controllers/create/subcommands/environment/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ mod tests;
1212

1313
// Re-export the main handler function, error types, and config loader
1414
pub use config_loader::ConfigLoader;
15-
pub use errors::{ConfigFormat, CreateSubcommandError};
15+
pub use errors::{ConfigFormat, CreateEnvironmentCommandError};
1616
pub use handler::handle_environment_creation;

0 commit comments

Comments
 (0)