Error Wrapping

There are three main options for propagating errors if a call fails:

  • Return the original error if there is no additional context to add and youwant to maintain the original error type.
  • Add context using "pkg/errors".Wrap so that the error message providesmore context and "pkg/errors".Cause can be used to extract the originalerror.
  • Use fmt.Errorf if the callers do not need to detect or handle thatspecific error case. It is recommended to add context where possible so that instead of a vagueerror such as "connection refused", you get more useful errors such as"call service foo: connection refused".

When adding context to returned errors, keep the context succinct by avoidingphrases like "failed to", which state the obvious and pile up as the errorpercolates up through the stack:

BadGood
  1. s, err := store.New()
  2. if err != nil {
  3. return fmt.Errorf(
  4. "failed to create new store: %s", err)
  5. }
  1. s, err := store.New()
  2. if err != nil {
  3. return fmt.Errorf(
  4. "new store: %s", err)
  5. }
  1. failed to x: failed to y: failed to create new store: the error
  1. x: y: new store: the error

However once the error is sent to another system, it should be clear themessage is an error (e.g. an err tag or "Failed" prefix in logs).

See also Don't just check errors, handle them gracefully.