Errors from goroutines in Go
A goroutine cannot return, so the error travels on a channel.
var ErrFetch = errors.New("fetch failed")
type result struct {
url string
err error
}
func fetchAll(urls []string) error {
results := make(chan result, len(urls))
var wg sync.WaitGroup
for _, url := range urls {
wg.Go(func() {
var err error
if strings.HasPrefix(url, "bad") {
err = fmt.Errorf("fetch %s: %w", url, ErrFetch)
}
results <- result{url: url, err: err}
})
}
wg.Wait()
close(results)
var problems error
for r := range results {
problems = errors.Join(problems, r.err)
}
return problems
}
How it works
- Every worker sends its result, error included.
- The collector decides whether one failure stops everything.
- Never just log and drop it inside the goroutine.
Keywords and builtins used here
chancloseerrorforfunciflenmakerangereturnstringstructtypevar
The run, in numbers
- Lines
- 29
- Characters to type
- 501
- Tokens
- 136
- Three-star pace
- 110 tpm
At the three-star pace of 110 tokens a minute, this run takes about 74 seconds.
Step 1 of 1 in Errors across goroutines, step 14 of 15 in Errors.