liveBook · Manning

Error wrapping

As explained in 100 Go Mistakes and How to Avoid Them

Error wrapping is the practice of attaching contextual information to an error while preserving the underlying error for propagation and inspection.

A common mistake is to add an error message without deciding whether callers still need the underlying error. Wrapping adds context or marks an error while keeping the original available for inspection. In Go 1.13 and later, fmt.Errorf with %w wraps; %v includes the message but does not preserve the error for unwrapping. section 7.2

Return context instead of logging twice

If coordinate validation fails, logging inside both the validator and GetRoute produces two logs for one failure. Returning the error without context avoids duplicate handling but loses whether source or target coordinates failed. Wrap at the call site instead: if err := validateCoordinates(srcLat, srcLng); err != nil { return Route{}, fmt.Errorf("failed to validate source coordinates: %w", err) } The caller can log once and still receive both the location of the failure and the validation error. section 7.5

Check through the wrapper

A direct type switch can recognize a transientError returned by a database call, then stop recognizing it when an intermediate function returns fmt.Errorf("failed to get transaction %s: %w", id, err). The outer error is no longer directly a transientError. Use errors.As(err, &transientError{}) to search the chain so an HTTP handler can still choose 503 rather than its default 400. section 7.3

Choose how much of the error to expose:

  • Return err directly when there is no useful context or marking to add. section 7.2
  • Use %w when callers should inspect the underlying error; use a custom error type when the wrapper itself must mark a specific kind of failure. section 7.2
  • Use %v when adding a message but deliberately not exposing the underlying error. Exposure can couple callers to that error; check wrapped types with errors.As and wrapped values with errors.Is. section 7.2 section 7.8

How 100 Go Mistakes and How to Avoid Them covers it

How deep it goes
Contrasts direct returns, custom types, %w, and %v, then traces a failed type check and its errors.As correction.
Examples
Uses coordinate-validation logs and a transaction HTTP handler whose wrapped transient error defeats a direct type switch.
What it assumes
Assumes familiarity with Go error returns and handlers while defining what wrapping preserves.
What you can do after
Diagnose/debug with it by replacing failed direct type checks with errors.As and returning contextual errors without duplicate logging.
How it connects
Connects error wrapping to error types, error sentinels, errors.As, errors.Is, and logging.

Also explained in

Compare how 3 books explain error wrapping →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Go Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.