Error Handling
Channel Error Handling Strategies
Error handling in concurrent Go programs requires careful design to prevent goroutine leaks and ensure robust communication.
Basic Error Propagation
func processData(ch <-chan int) error {
for value := range ch {
if value < 0 {
return fmt.Errorf("invalid negative value: %d", value)
}
// Process value
}
return nil
}
Error Channel Pattern
func worker(data <-chan int, errCh chan<- error) {
for value := range data {
if err := processValue(value); err != nil {
errCh <- err
return
}
}
}
func main() {
dataCh := make(chan int)
errCh := make(chan error, 1)
go worker(dataCh, errCh)
select {
case err := <-errCh:
fmt.Println("Error occurred:", err)
case <-time.After(5 * time.Second):
fmt.Println("Operation completed successfully")
}
}
Error Handling Strategies
Strategy |
Description |
Use Case |
Error Channel |
Separate error communication |
Multiple concurrent operations |
Context Cancellation |
Propagate cancellation signals |
Complex workflows |
Panic and Recover |
Last-resort error handling |
Unrecoverable errors |
Context-Based Error Handling
func processWithContext(ctx context.Context, ch <-chan int) error {
for {
select {
case <-ctx.Done():
return ctx.Err()
case value, ok := <-ch:
if !ok {
return nil
}
if err := processValue(value); err != nil {
return err
}
}
}
}
Error Propagation Workflow
graph TD
A[Goroutine] -->|Process Data| B{Error Occurred?}
B -->|Yes| C[Send to Error Channel]
B -->|No| D[Continue Processing]
C -->|Notify| E[Main Goroutine]
Advanced Error Handling Techniques
1. Multiple Error Channels
type Result struct {
Value int
Err error
}
func worker(ch <-chan int, results chan<- Result) {
for value := range ch {
result := Result{Value: value}
if value < 0 {
result.Err = fmt.Errorf("negative value: %d", value)
}
results <- result
}
}
Best Practices
- Use buffered error channels to prevent blocking
- Implement timeouts for long-running operations
- Close error channels when no longer needed
- Use context for cancellation and timeout management
LabEx Recommendation
In LabEx concurrent programming scenarios, always design error handling mechanisms that provide clear error visibility and graceful degradation.
Common Error Handling Antipatterns
- Ignoring errors
- Blocking indefinitely
- Not closing channels
- Overcomplicated error management