पाठ 11 / 26

Wrapping and Inspecting Errors

Add context, keep the cause.

fmt.Errorf %w, errors.Is, errors.As

Add context as errors travel up with fmt.Errorf("find user %d: %w", id, err); %w wraps the original so it is not lost. errors.Is(err, target) checks whether any error in the chain matches a sentinel value (like ErrNotFound or fs.ErrNotExist); errors.As(err, &target) finds an error of a specific type and gives you its fields. Compare errors with these functions, not with == or string matching, so wrapping does not break checks.

Explicit, wrapped, recoverable

Go treats errors as values, wraps them with context, and reserves panics for truly exceptional situations.

Three ideas: wrapping and checking errors, defer and recover, error design.
Figure 4.1 — Errors, defer and recovery.

Sentinel, typed and standard library errors, run

I ran this with Go 1.27.1 (go run . in a module named demo, standard library only). The wrapped error keeps its message chain and still matches ErrNotFound; errors.As extracts the ValidationError and its field; opening a missing file matches fs.ErrNotExist.

package main

import (
	"errors"
	"fmt"
	"io/fs"
	"os"
)

var ErrNotFound = errors.New("not found") // sentinel error

type ValidationError struct{ Field string }

func (e *ValidationError) Error() string { return "invalid " + e.Field }

func findUser(id int) error {
	if id <= 0 {
		return &ValidationError{Field: "id"}
	}
	return fmt.Errorf("find user %d: %w", id, ErrNotFound) // wrap with context
}

func main() {
	err := findUser(7)
	fmt.Println(err)
	fmt.Println("is ErrNotFound:", errors.Is(err, ErrNotFound))

	var ve *ValidationError
	err = findUser(-1)
	fmt.Println("as ValidationError:", errors.As(err, &ve), ve.Field)

	_, err = os.Open("missing.txt")
	fmt.Println("file missing:", errors.Is(err, fs.ErrNotExist))
}

Output:

find user 7: not found
is ErrNotFound: true
as ValidationError: true id
file missing: true

Wrap with context once per layer

Each layer adds what it knows (operation, ids) so the final message reads like a stack of reasons.

त्वरित जाँच: Which verb in fmt.Errorf wraps an error so errors.Is can find it?

  • %e
  • %v
  • %s
  • %w
Answer

%w — %w preserves the chain.