Go module with set of core packages every Go project needs. Minimal API, battle-tested, strictly versioned and with only two transient dependencies-- davecgh/go-spew and google/go-cmp.
Maintained by experienced Go developers, including author of the Efficient Go book.
Import it using go get github.com/efficientgo/core@latest
.
This module contains packages around the following functionalities:
NOTE: Click on each package to see usage examples in pkg.go.dev!
- github.com/efficientgo/core/errors is an improved and minimal version of the popular
pkg/errors
package (archived) allowing reliable wrapping of errors with stacktrace. Unfortunately, the standard library recommended error wrapping using%+w
is prone to errors and does not support stacktraces. For example:
var (
err = errors.New("root error while doing A")
wrapped = errors.Wrap(err, "while doing B")
)
- github.com/efficientgo/core/merrors implements type safe collection of multiple errors. It presentings them in a unified way as a single
error
interface.
func CloseAll(closers []io.Closer) error {
errs := merrors.New()
for _, c := range closers {
errs.Add(c.Close())
}
return errs.Err()
}
- github.com/efficientgo/core/errcapture offers readable and robust error handling in defer statement using Go return arguments.
func DoAndClose(f *os.File) (err error) {
defer errcapture.Do(&err, f.Close, "close file at the end")
// Do something...
if err := do(); err != nil {
return err
}
return nil
}
- github.com/efficientgo/core/logerrcapture is similar to
errcapture
, but instead of appending potential error it logs it using logger interface.
func DoAndClose(f *os.File, logger logerrcapture.Logger) error {
defer logerrcapture.Do(logger, f.Close, "close file at the end")
// Do something...
if err := do(); err != nil {
return err
}
return nil
}
- github.com/efficientgo/core/runutil offers
Retry
andRepeat
functions which is often need in Go production code (e.g. repeating operation periodically) as well as tests (e.g. waiting on eventual results instead of sleeping).
// Repeat every 1 second until context is done (e.g. cancel or timeout) or
// function returns error.
err := runutil.Repeat(1*time.Second, ctx.Done(), func() error {
// ...
return err // Ups, error - don't repeat anymore!
})
// Retry every 1 second until context is done (e.g. cancel or timeout) or
// function returns nil.
err := runutil.Retry(1*time.Second, ctx.Done(), func() error {
// ...
return nil // Done, no need to retry!
})
- github.com/efficientgo/core/backoff offers backoff timers which increases wait time on every retry, incredibly useful in distributed system timeout functionalities.
- github.com/efficientgo/core/testutil is a minimal testing utility with only few functions like
Assert
,Ok
,NotOk
for errors andEquals
. It's an alternative to testify project which has a bit more bloated interface and larger dependencies.
func TestSomething(t *testing.T) {
got, err := something()
testutil.Ok(t, err)
testutil.Equals(t, expected, got, "expected different thing from something")
}
@bisakhmondal
(errors
package).@bwplotka
@GiedriusS
(errcapture
andlogerrcapture
)