Skip to content

Commit b49bcc0

Browse files
committed
refactor: [#107] simplify error handling with From trait for ProgressReporterError
- Add From<ProgressReporterError> implementations for DestroySubcommandError and CreateSubcommandError - Replace verbose .map_err(|e| Error::ProgressReportingFailed { source: e }) with simple ? operator - Eliminates ~80 lines of boilerplate across destroy and create handlers - Follows idiomatic Rust patterns for automatic error conversion
1 parent cb10deb commit b49bcc0

File tree

4 files changed

+50
-64
lines changed

4 files changed

+50
-64
lines changed

src/presentation/commands/create/errors.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ Tip: This is a critical bug - please report it with full logs using --log-output
130130
},
131131
}
132132

133+
// ============================================================================
134+
// ERROR CONVERSIONS
135+
// ============================================================================
136+
137+
impl From<ProgressReporterError> for CreateSubcommandError {
138+
fn from(source: ProgressReporterError) -> Self {
139+
Self::ProgressReportingFailed { source }
140+
}
141+
}
142+
133143
impl CreateSubcommandError {
134144
/// Provides detailed troubleshooting guidance for this error
135145
///

src/presentation/commands/create/subcommands/environment.rs

Lines changed: 19 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -57,45 +57,31 @@ pub fn handle_environment_creation(
5757
let mut progress = ProgressReporter::new(user_output.clone(), 3);
5858

5959
// Step 1: Load configuration
60-
progress
61-
.start_step("Loading configuration")
62-
.map_err(|e| CreateSubcommandError::ProgressReportingFailed { source: e })?;
60+
progress.start_step("Loading configuration")?;
6361
let config = load_configuration(progress.output(), env_file)?;
64-
progress
65-
.complete_step(Some(&format!(
66-
"Configuration loaded: {}",
67-
config.environment.name
68-
)))
69-
.map_err(|e| CreateSubcommandError::ProgressReportingFailed { source: e })?;
62+
progress.complete_step(Some(&format!(
63+
"Configuration loaded: {}",
64+
config.environment.name
65+
)))?;
7066

7167
// Step 2: Initialize dependencies
72-
progress
73-
.start_step("Initializing dependencies")
74-
.map_err(|e| CreateSubcommandError::ProgressReportingFailed { source: e })?;
68+
progress.start_step("Initializing dependencies")?;
7569
let command_handler = factory.create_create_handler(&ctx);
76-
progress
77-
.complete_step(None)
78-
.map_err(|e| CreateSubcommandError::ProgressReportingFailed { source: e })?;
70+
progress.complete_step(None)?;
7971

8072
// Step 3: Execute create command (provision infrastructure)
81-
progress
82-
.start_step("Creating environment")
83-
.map_err(|e| CreateSubcommandError::ProgressReportingFailed { source: e })?;
73+
progress.start_step("Creating environment")?;
8474
let environment = execute_create_command(progress.output(), &command_handler, config)?;
85-
progress
86-
.complete_step(Some(&format!(
87-
"Instance created: {}",
88-
environment.instance_name().as_str()
89-
)))
90-
.map_err(|e| CreateSubcommandError::ProgressReportingFailed { source: e })?;
75+
progress.complete_step(Some(&format!(
76+
"Instance created: {}",
77+
environment.instance_name().as_str()
78+
)))?;
9179

9280
// Complete with summary
93-
progress
94-
.complete(&format!(
95-
"Environment '{}' created successfully",
96-
environment.name().as_str()
97-
))
98-
.map_err(|e| CreateSubcommandError::ProgressReportingFailed { source: e })?;
81+
progress.complete(&format!(
82+
"Environment '{}' created successfully",
83+
environment.name().as_str()
84+
))?;
9985

10086
// Display final results
10187
display_creation_results(progress.output(), &environment);
@@ -131,9 +117,7 @@ fn load_configuration(
131117
) -> Result<EnvironmentCreationConfig, CreateSubcommandError> {
132118
user_output
133119
.lock()
134-
.map_err(|_| CreateSubcommandError::ProgressReportingFailed {
135-
source: crate::presentation::progress::ProgressReporterError::UserOutputMutexPoisoned,
136-
})?
120+
.map_err(|_| crate::presentation::progress::ProgressReporterError::UserOutputMutexPoisoned)?
137121
.progress(&format!(
138122
"Loading configuration from '{}'...",
139123
env_file.display()
@@ -175,19 +159,15 @@ fn execute_create_command(
175159
) -> Result<Environment, CreateSubcommandError> {
176160
user_output
177161
.lock()
178-
.map_err(|_| CreateSubcommandError::ProgressReportingFailed {
179-
source: crate::presentation::progress::ProgressReporterError::UserOutputMutexPoisoned,
180-
})?
162+
.map_err(|_| crate::presentation::progress::ProgressReporterError::UserOutputMutexPoisoned)?
181163
.progress(&format!(
182164
"Creating environment '{}'...",
183165
config.environment.name
184166
));
185167

186168
user_output
187169
.lock()
188-
.map_err(|_| CreateSubcommandError::ProgressReportingFailed {
189-
source: crate::presentation::progress::ProgressReporterError::UserOutputMutexPoisoned,
190-
})?
170+
.map_err(|_| crate::presentation::progress::ProgressReporterError::UserOutputMutexPoisoned)?
191171
.progress("Validating configuration and creating environment...");
192172

193173
#[allow(clippy::manual_inspect)]

src/presentation/commands/destroy/errors.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,16 @@ Tip: This is a critical bug - please report it with full logs using --log-output
9191
},
9292
}
9393

94+
// ============================================================================
95+
// ERROR CONVERSIONS
96+
// ============================================================================
97+
98+
impl From<ProgressReporterError> for DestroySubcommandError {
99+
fn from(source: ProgressReporterError) -> Self {
100+
Self::ProgressReportingFailed { source }
101+
}
102+
}
103+
94104
impl DestroySubcommandError {
95105
/// Get detailed troubleshooting guidance for this error
96106
///

src/presentation/commands/destroy/handler.rs

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -68,50 +68,36 @@ pub fn handle_destroy_command(
6868
let mut progress = ProgressReporter::new(user_output.clone(), 3);
6969

7070
// Step 1: Validate environment name
71-
progress
72-
.start_step("Validating environment")
73-
.map_err(|e| DestroySubcommandError::ProgressReportingFailed { source: e })?;
71+
progress.start_step("Validating environment")?;
7472
let env_name = EnvironmentName::new(environment_name.to_string()).map_err(|source| {
7573
DestroySubcommandError::InvalidEnvironmentName {
7674
name: environment_name.to_string(),
7775
source,
7876
}
7977
})?;
80-
progress
81-
.complete_step(Some(&format!(
82-
"Environment name validated: {environment_name}"
83-
)))
84-
.map_err(|e| DestroySubcommandError::ProgressReportingFailed { source: e })?;
78+
progress.complete_step(Some(&format!(
79+
"Environment name validated: {environment_name}"
80+
)))?;
8581

8682
// Step 2: Initialize dependencies
87-
progress
88-
.start_step("Initializing dependencies")
89-
.map_err(|e| DestroySubcommandError::ProgressReportingFailed { source: e })?;
83+
progress.start_step("Initializing dependencies")?;
9084
let command_handler = factory.create_destroy_handler(&ctx);
91-
progress
92-
.complete_step(None)
93-
.map_err(|e| DestroySubcommandError::ProgressReportingFailed { source: e })?;
85+
progress.complete_step(None)?;
9486

9587
// Step 3: Execute destroy command (tear down infrastructure)
96-
progress
97-
.start_step("Tearing down infrastructure")
98-
.map_err(|e| DestroySubcommandError::ProgressReportingFailed { source: e })?;
88+
progress.start_step("Tearing down infrastructure")?;
9989
let _destroyed_env = command_handler.execute(&env_name).map_err(|source| {
10090
DestroySubcommandError::DestroyOperationFailed {
10191
name: environment_name.to_string(),
10292
source,
10393
}
10494
})?;
105-
progress
106-
.complete_step(Some("Infrastructure torn down"))
107-
.map_err(|e| DestroySubcommandError::ProgressReportingFailed { source: e })?;
95+
progress.complete_step(Some("Infrastructure torn down"))?;
10896

10997
// Complete with summary
110-
progress
111-
.complete(&format!(
112-
"Environment '{environment_name}' destroyed successfully"
113-
))
114-
.map_err(|e| DestroySubcommandError::ProgressReportingFailed { source: e })?;
98+
progress.complete(&format!(
99+
"Environment '{environment_name}' destroyed successfully"
100+
))?;
115101

116102
Ok(())
117103
}

0 commit comments

Comments
 (0)