Error Handling Strategies
Comprehensive Error Management in Command Execution
Effective error handling is critical for creating robust and reliable Golang applications that interact with system commands.
Error Handling Patterns
1. Defensive Error Handling
func safeCommandExecution(command string, args ...string) ([]byte, error) {
cmd := exec.Command(command, args...)
// Set timeout to prevent hanging
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
cmd.Context = ctx
output, err := cmd.CombinedOutput()
if err != nil {
return nil, fmt.Errorf("command execution failed: %w", err)
}
return output, nil
}
2. Error Handling Workflow
graph TD
A[Execute Command] --> B{Error Occurred?}
B -->|Yes| C[Log Error]
C --> D[Determine Recovery Strategy]
D --> E[Retry/Fallback/Abort]
B -->|No| F[Process Output]
Error Handling Strategies
Strategy |
Description |
Use Case |
Logging |
Record error details |
Debugging |
Retry |
Attempt command again |
Transient errors |
Fallback |
Use alternative method |
Critical operations |
Abort |
Stop execution |
Unrecoverable errors |
Advanced Error Handling Techniques
Custom Error Wrapper
type CommandError struct {
Command string
Args []string
Err error
Output []byte
}
func (ce *CommandError) Error() string {
return fmt.Sprintf("Command %s failed: %v", ce.Command, ce.Err)
}
func executeWithCustomError(command string, args ...string) error {
cmd := exec.Command(command, args...)
output, err := cmd.CombinedOutput()
if err != nil {
return &CommandError{
Command: command,
Args: args,
Err: err,
Output: output,
}
}
return nil
}
Error Recovery Mechanisms
Retry Logic
func executeWithRetry(command string, args []string, maxRetries int) ([]byte, error) {
var lastErr error
for attempt := 0; attempt < maxRetries; attempt++ {
output, err := exec.Command(command, args...).CombinedOutput()
if err == nil {
return output, nil
}
lastErr = err
time.Sleep(time.Second * time.Duration(attempt+1))
}
return nil, fmt.Errorf("failed after %d attempts: %w", maxRetries, lastErr)
}
Logging and Monitoring
Structured Error Logging
func logCommandError(err error) {
if cmdErr, ok := err.(*CommandError); ok {
log.Printf(
"Command Execution Error: Command=%s, Args=%v, Error=%v, Output=%s",
cmdErr.Command,
cmdErr.Args,
cmdErr.Err,
string(cmdErr.Output),
)
}
}
LabEx Recommendation
LabEx emphasizes creating resilient error handling strategies that provide clear insights and enable effective troubleshooting.
Key Principles
- Always handle potential errors
- Provide context with errors
- Implement appropriate recovery mechanisms
- Log errors for diagnostic purposes
- Use timeouts to prevent indefinite waiting