Errors
Intermediate · Functions & Errors
Go treats errors as ordinary values returned from functions, not exceptions. These exercises cover the idiomatic toolkit:
- returning and checking
errorvalues (errors.New) - wrapping with
fmt.Errorf("...: %w", err)and matching witherrors.Is - custom error types and extracting them with
errors.As panic/recoverand why it is a last resort, not flow control
Resources
Section titled “Resources”- Effective Go: Errors
- Go blog: Errors are values
- Go blog: Working with Errors in Go 1.13
- Go by Example: Errors
Exercises
Section titled “Exercises”errors1 test
Section titled “errors1 test”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`.errors2 test
Section titled “errors2 test”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)errors3 test
Section titled “errors3 test”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.errors4 test
Section titled “errors4 test”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.errors5 test
Section titled “errors5 test”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...)