Go
Error handling
Add error handling in workers and a WaitGroup.
Error handling and shutdown
When a job fails there are two options: report the error with the result and continue, or stop all jobs at the first error. For the second, golang.org/x/sync/errgroup is ideal:
g, ctx := errgroup.WithContext(ctx)
g.SetLimit(3) // at most 3 concurrent jobs
for _, yol := range dosyalar {
g.Go(func() error { return isle(ctx, yol) })
}
if err := g.Wait(); err != nil {
log.Println("ilk hata:", err)
}
The first error cancels ctx; the other jobs check ctx and stop early.
Joining errors
If you want "try every job, show all errors at the end", collect the errors and turn them into one with errors.Join (Go 1.20):
var hatalar []error
for s := range sonuclar {
if s.Hata != nil {
hatalar = append(hatalar, fmt.Errorf("iş %d: %w", s.IsID, s.Hata))
}
}
return errors.Join(hatalar...) // nil if there are none
errors.Is can still find every error inside the joined error.
Exercise Collecting errors
Run three jobs; the job with ID 1 returns errors.New("okunamadı"). Wrap the errors from the results with fmt.Errorf("iş %d: %w", ...), collect them and print the result of errors.Join.
Show example solution
package main
import (
"errors"
"fmt"
"sync"
)
type Sonuc struct {
IsID int
Hata error
}
func main() {
sonuclar := make(chan Sonuc)
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
var err error
if id == 1 {
err = errors.New("okunamadı")
}
sonuclar <- Sonuc{id, err}
}(i)
}
go func() {
wg.Wait()
close(sonuclar)
}()
var hatalar []error
for s := range sonuclar {
if s.Hata != nil {
hatalar = append(hatalar, fmt.Errorf("iş %d: %w", s.IsID, s.Hata))
}
}
fmt.Println(errors.Join(hatalar...))
}
Test yourself
-
What does <code>g.Wait()</code> return in an errgroup?
- The first non-nil error
- A list of all errors
- The last error
- Always nil
Show answer
The first non-nil error — errgroup keeps the first error and Wait returns it; if all errors are needed, use the result-channel approach or errors.Join.
-
Join the errors
return errors.____(hatalar...)
Show answer
return errors.Join(hatalar...)
-
Strategy
- Sonuc.Hata
- Report the error, continue
- errgroup
- Stop at the first error
- errors.Join
- Show all errors
- g.SetLimit(3)
- Concurrency limit
Next lesson: context.Background