Error Handling
Explicit error values and wrapping. Results appear in the same fence: same-line // comments when short, multiline // blocks below the sample when not.
Search across all documentation pages
Explicit error values and wrapping. Results appear in the same fence: same-line // comments when short, multiline // blocks below the sample when not.
Simple sentinel or message errors.
err := errors.New("boom")
err.Error() // "boom"Wrap with %w for errors.Is/As.
base := errors.New("root")
err := fmt.Errorf("load: %w", base)
errors.Is(err, base) // trueCheck sentinel in a chain.
var ErrNotFound = errors.New("not found")
err := fmt.Errorf("user: %w", ErrNotFound)
errors.Is(err, ErrNotFound) // trueExtract typed error from chain.
type MyErr struct{ Code int }
func (e *MyErr) Error() string { return "my" }
err := fmt.Errorf("x: %w", &MyErr{Code: 7})
var me *MyErr
errors.As(err, &me) // true
// me.Code == 7Recover only in defer; convert to error at boundaries.
func safe() (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic: %v", r)
}
}()
panic("x")
}
// safe() returns errorJoin with errors.Join (Go 1.20+).
err := errors.Join(errors.New("a"), errors.New("b"))
err != nil // trueStruct implementing Error().
type E struct{ Msg string }
func (e E) Error() string { return e.Msg }
E{Msg: "nope"}.Error() // "nope"Idiomatic if err != nil { return }.
// v, err := f()
// if err != nil { return err }
// use vManual unwrap if needed.
base := errors.New("b")
err := fmt.Errorf("a: %w", base)
errors.Unwrap(err) == base // true_ = only when intentionally discarding.
_ = os.Remove("tmp") // best-effort cleanup%v stringifies; %w wraps.
e := errors.New("x")
fmt.Errorf("%v", e).Error() // "x" (not wrap)Standard library sentinels.
errors.Is(fs.ErrNotExist, fs.ErrNotExist) // trueCheck context errors.
errors.Is(context.Canceled, context.Canceled) // truePanic on error in init/tests - not request path.
// func must[T any](v T, err error) T { if err != nil { panic(err) }; return v }Keep Error() messages stable for logs, not for branching - use Is/As.
// branch on errors.Is, not strings.Contains(err.Error())Stack versions: Go 1.26.x · chi/gin/echo latest (verify at build)
Reviewed by Chris St. John·Last updated Jul 18, 2026