Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

If the client needs to detect the error, and you have created a simple error using errors.New, use a var for the error.

Bad

Good

Code Block
languagego
// package foo

func Open() error {
  return errors.New("could not open")
}

// package bar

  if err := foo.Open(); err != nil {
    if err.Error() == "could not open" {
      // handle
    } else {
      panic("unknown error")
    }
  }
Code Block
// package foo

var ErrCouldNotOpen = errors.New("could not open")

func Open() error {
  return ErrCouldNotOpen
}

// package bar

if err := foo.Open(); err != nil {
  if errors.Is(err, foo.ErrCouldNotOpen) {
    // handle
  } else {
    return errors.Wrap(err, "unknown error")
  }
}

...

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

Bad

Good

Code Block
languagego
s, err := store.New()
if err != nil {
    return errors.Newf(
        "failed to create new store: %s", err)
}
Code Block
languagego
s, err := store.New()
if err != nil {
    return errors.Wrap(
        "new store", err)
}
Code Block
failed to x: failed to y: failed to create new store: the error
Code Block
x: y: new store: the error

...