Go
Beginner
1 min read
Idiomatic Error Handling Patterns
Example
package main
import (
"errors"
"fmt"
"io"
"strings"
)
// errWriter accumulates the first write error.
type errWriter struct {
w io.Writer
err error
}
func (ew *errWriter) write(s string) {
if ew.err != nil {
return
}
_, ew.err = fmt.Fprint(ew.w, s)
}
// Inline error handling in a pipeline
func buildMessage(name, greeting string) (string, error) {
if name == "" {
return "", errors.New("name must not be empty")
}
if greeting == "" {
return "", errors.New("greeting must not be empty")
}
return greeting + ", " + name + "!", nil
}
// Collecting errors from goroutines via channel
func runTasks(tasks []func() error) []error {
errs := make(chan error, len(tasks))
for _, t := range tasks {
t := t
go func() { errs <- t() }()
}
var result []error
for range tasks {
if err := <-errs; err != nil {
result = append(result, err)
}
}
return result
}
func main() {
var sb strings.Builder
ew := &errWriter{w: &sb}
ew.write("Hello")
ew.write(", ")
ew.write("World")
ew.write("!")
if ew.err != nil {
fmt.Println("write error:", ew.err)
} else {
fmt.Println(sb.String())
}
msg, err := buildMessage("Go", "Hello")
if err != nil { fmt.Println(err) } else { fmt.Println(msg) }
tasks := []func() error{
func() error { return nil },
func() error { return errors.New("task 2 failed") },
func() error { return nil },
func() error { return errors.New("task 4 failed") },
}
for _, e := range runTasks(tasks) {
fmt.Println("task error:", e)
}
}