Advanced Techniques
Custom Error Types and Interfaces
Defining Complex Error Structures
type CustomError struct {
Code int
Message string
Context map[string]interface{}
}
func (e *CustomError) Error() string {
return fmt.Sprintf("Error %d: %s", e.Code, e.Message)
}
Error Wrapping and Contextualization
Advanced Error Handling
func wrapError(err error, message string) error {
return fmt.Errorf("%s: %w", message, err)
}
func processData(data []byte) error {
if len(data) == 0 {
return wrapError(errors.New("empty data"), "data processing failed")
}
return nil
}
Error Handling Flow
graph TD
A[Receive Error] --> B{Error Type?}
B -->|Recoverable| C[Log and Retry]
B -->|Critical| D[Graceful Shutdown]
C --> E[Retry Mechanism]
D --> F[Clean Resources]
Error Handling Strategies
Strategy |
Description |
Use Case |
Retry Pattern |
Automatic retry on transient errors |
Network operations |
Circuit Breaker |
Prevent repeated failure attempts |
External service calls |
Fallback Mechanism |
Provide alternative execution path |
Service degradation |
Retry Mechanism Implementation
func retryOperation(maxRetries int, fn func() error) error {
var lastErr error
for attempt := 0; attempt < maxRetries; attempt++ {
if err := fn(); err != nil {
lastErr = err
time.Sleep(time.Second * time.Duration(attempt+1))
continue
}
return nil
}
return fmt.Errorf("operation failed after %d attempts: %v",
maxRetries, lastErr)
}
Advanced Error Tracking
Structured Logging
type ErrorTracker struct {
logger *log.Logger
errors []error
}
func (et *ErrorTracker) Track(err error) {
if err != nil {
et.errors = append(et.errors, err)
et.logger.Printf("Tracked error: %v", err)
}
}
Error Handling Patterns
graph TD
A[Error Detection] --> B{Error Classification}
B -->|Transient| C[Retry]
B -->|Permanent| D[Fallback]
B -->|Critical| E[Escalation]
C --> F[Retry Logic]
D --> G[Alternative Execution]
E --> H[Alert System]
Comprehensive Error Management
type ErrorHandler struct {
retryCount int
timeout time.Duration
}
func (eh *ErrorHandler) Handle(operation func() error) error {
return retry.Do(
operation,
retry.Attempts(uint(eh.retryCount)),
retry.Delay(eh.timeout),
retry.OnRetry(func(n uint, err error) {
log.Printf("Retry %d: %v", n, err)
}),
)
}
Technique |
Overhead |
Complexity |
Simple Error Checking |
Low |
Low |
Retry Mechanism |
Medium |
Medium |
Complex Error Tracking |
High |
High |
Best Practices
- Use context-rich error information
- Implement intelligent retry mechanisms
- Avoid over-engineering error handling
- Maintain clear error communication
LabEx recommends a balanced approach to advanced error handling, focusing on readability and system resilience.