README

Yet another errors package for Go.

Import as zgo.at/errors; godoc.

This is based on the new errors API introduced in Go 1.13 with the additions:

  1. Add Wrap(err, "some context") and Wrapf(err, "some context", ...), which return nil if the passed error is nil.

    I tried using the fmt.Errorf("...: %w", err) pattern, but I found I missed being able to do:

    func f() error {
        return errors.Wrap(f2(), "context")
    }
    

    Which I find much more convenient than:

    func f() error {
        err := f2()
        if err != nil {
            return fmt.Errorf("context: %w", err)
        }
        return nil
    }
    
  2. A stack trace is added with erorrs.New(), errors.Errorf(), and erorrs.Wrap() I know it's not needed with appropriate context but sometimes I accidentally add the same context more than once, or just want to quickly see where exactly the error is coming from. Especially on dev it's much more convenient.

    You can use errors.Package to only add stack traces for a specific package. For example errors.Package = "zgo.at/goatcounter" will only add trace lines in zgo.at/goatcounter/...

    You can control the maximum stack size with errors.StackSize; set to 0 to disable adding stack traces altogether (i.e. on production).

  3. Group type for collecting grouped errors:

     errs := NewGroup(20)  // 20 is the maximum amount of errors
     for {
         err := doStuff()
         if err.Append(err) { // Won't append on nil, returns false if it's nil.
             continue
         }
     }
    
     fmt.Println(errs)        // Print all errors (if any).
     return errs.ErrorOrNil() // No errors? Returns nil.
    

Documentation

Overview

Package errors adds some useful error helpers.

Index

Constants

This section is empty.

Variables

View Source
var (
	// Package to add trace lines for; if blank all traces are added.
	Package string

	// StackSize is the maximum stack sized added to errors. Set to 0 to
	// disable.
	StackSize int = 32
)

Functions

func As

func As(err error, target interface{}) bool

func Errorf

func Errorf(f string, a ...interface{}) error

func Is

func Is(err, target error) bool

func New

func New(text string) error

func Unwrap

func Unwrap(err error) error

func Wrap

func Wrap(err error, s string) error

Wrap an error with fmt.Errorf(), returning nil if err is nil.

func Wrapf

func Wrapf(err error, format string, a ...interface{}) error

Wrapf an error with fmt.Errorf(), returning nil if err is nil.

Types

type Group

type Group struct {
	// Maximum number of errors; calls to Append() won't do anything if the
	// number of errors is larger than this.
	MaxSize int
	// contains filtered or unexported fields
}

Group multiple errors.

func NewGroup

func NewGroup(maxSize int) *Group

NewGroup create a new Group instance. It will record a maximum of maxSize errors. Set to 0 for no limit.

func (*Group) Append

func (g *Group) Append(err error) bool

Append a new error to the list; this is thread-safe.

It won't do anything if the error is nil, in which case it will return false. This makes appending errors in a loop slightly nicer:

for {
    err := do()
    if errors.Append(err) {
        continue
    }
}

func (Group) Error

func (g Group) Error() string

func (*Group) ErrorOrNil

func (g *Group) ErrorOrNil() error

ErrorOrNil returns itself if there are errors, or nil otherwise.

It avoids an if-check at the end:

return errs.ErrorOrNil()

func (Group) Len

func (g Group) Len() int

Len returns the number of errors.

type StackErr

type StackErr struct {
	// contains filtered or unexported fields
}

func (StackErr) Error

func (err StackErr) Error() string

func (StackErr) StackTrace

func (err StackErr) StackTrace() string

func (StackErr) Unwrap

func (err StackErr) Unwrap() error

type StackTracer

type StackTracer interface {
	StackTrace() string
}

Source Files