Skip to content

Errors

Intermediate · Functions & Errors

Go treats errors as ordinary values returned from functions, not exceptions. These exercises cover the idiomatic toolkit:

  • returning and checking error values (errors.New)
  • wrapping with fmt.Errorf("...: %w", err) and matching with errors.Is
  • custom error types and extracting them with errors.As
  • panic/recover and why it is a last resort, not flow control

In Go, errors are ordinary values returned alongside results.

Show hint
Errors are values. Return them, do not throw them.
Import "errors" and return errors.New("...") when b == 0.
Check the result at the call site with `if err != nil`.

Source

Wrapping an error with %w keeps the original reachable via errors.Is.

Show hint
The %w verb wraps an error so errors.Is can unwrap and match it.
fmt.Errorf("lookup %q: %w", id, ErrNotFound)

Source

A custom error type is any type implementing the error interface.

Show hint
Any type with an Error() string method satisfies the error interface.
Build the message from e.Field, e.g. fmt.Sprintf("%s is required", e.Field).
errors.As walks the wrap chain to find a *ValidationError.

Source

panic/recover is Go’s last-resort mechanism, not normal error handling.

Show hint
recover() only works inside a deferred function.
defer func() { if r := recover(); r != nil { err = fmt.Errorf("recovered: %v", r) } }()
A named return value (err) can be set from inside the deferred func.

Source

errors.Join (Go 1.20) bundles several errors into one. errors.Is then

Show hint
errors.Join bundles many errors; errors.Is matches any of them:
return errors.Join(errs...)

Source