Simple custom error wrapper utility library for my Go projects.
| .gitignore | ||
| errx.go | ||
| errx_test.go | ||
| example_test.go | ||
| go.mod | ||
| README.md | ||
| Taskfile.yml | ||
errx
Simple custom error wrapper utility library for my Go projects.
errx records the operation where each error happened and chains those
operations together as the error bubbles up. The result is a readable
breadcrumb instead of a runtime stack trace:
users.Get: user=42: db.Query: connection refused
Usage
Each function declares its op and wraps errors as it returns them:
import "git.juancwu.dev/juancwu/errx"
func (s *Store) Get(id int) (*User, error) {
const op = "users.Get"
row, err := s.db.Query(id)
if err != nil {
return nil, errx.Wrapf(op, err, "user=%d", id)
}
if row == nil {
return nil, errx.New(op, "not found")
}
return row, nil
}
The four constructors:
errx.New(op, msg) // fresh error, static msg
errx.Newf(op, format, args...) // fresh error, formatted msg
errx.Wrap(op, err) // wrap, no extra msg (nil-safe)
errx.Wrapf(op, err, format, args...) // wrap with formatted msg (nil-safe)
Wrap and Wrapf return nil when passed a nil error, so you can chain
them without an extra guard:
return errx.Wrap(op, s.commit())
Interop
*errx.Error implements Unwrap, so errors.Is and errors.As walk the
chain as expected:
if errors.Is(err, io.EOF) { ... }
var e *errx.Error
if errors.As(err, &e) {
log.Printf("op=%s", e.Op)
}