The Emperor takes care of all errors personally

Emperror

Mentioned in Awesome Go

GitHub Workflow Status Codecov Go Report Card Go Version PkgGoDev FOSSA Status

The Emperor takes care of all errors personally.

Go's philosophy encourages to gracefully handle errors whenever possible, but some times recovering from an error is not.

In those cases handling the error means making the best effort to record every detail for later inspection, doing that as high in the application stack as possible.

This project provides tools to make error handling easier.

Read more about the topic here:

Features

Installation

go get emperror.dev/emperror

Usage

Log errors

Logging is one of the most common target to record error events.

Emperror has two logger integrations by default:

Annotate errors passing through an error handler

Emperror can annotate errors with details as defined in emperror.dev/errors

package main

import (
	"emperror.dev/emperror"
	"emperror.dev/errors"
)

func main() {
	handler := emperror.WithDetails(newHandler(), "key", "value")

	err := errors.New("error")

	// handled error will receive the handler details
	handler.Handle(err)
}

Panics and recovers

package main

import (
	"emperror.dev/emperror"
	"emperror.dev/errors"
)

func main() {
	var handler emperror.Handler = newHandler()

	// Recover from panics and handle them as errors
	defer emperror.HandleRecover(handler)

	// nil errors will not panic
	emperror.Panic(nil)

	// this will panic if foo returns with a non-nil error
	// useful in main func for initial setup where "if err != nil" does not make much sense
	emperror.Panic(foo())
}

func foo() error {
	return errors.New("error")
}

Filter errors

Sometimes you might not want to handle certain errors that reach the error handler. A common example is a catch-all error handler in a server. You want to return business errors to the client.

package main

import (
	"emperror.dev/emperror"
	"emperror.dev/errors/match"
)

func main() {
	var handler emperror.Handler = emperror.WithFilter(newHandler(), match.Any{/*any emperror.ErrorMatcher*/})

    // errors matching the provided matcher will not be handled
	handler.Handle(err)
}

Development

Contributions are welcome! :)

  1. Clone the repository
  2. Make changes on a new branch
  3. Run the test suite:
    ./pleasew build
    ./pleasew test
    ./pleasew gotest
    ./pleasew lint
  4. Commit, push and open a PR

License

The MIT License (MIT). Please see License File for more information.

FOSSA Status

Owner
Emperror
Error handling tools and best practices for Go applications
Emperror
Comments
  • How to get each error in MultiErrorBuilder?

    How to get each error in MultiErrorBuilder?

    When using the MultiErrorBuilder and having multiple errors, I'm unable to get to each error. (b *MultiErrorBuilder) ErrOrNil() creates an object of the type multiError - which would allow me to use (e *multiError) Errors(), but is returned as type error (which is good). From outside, I'm unable to cast to this type, as it is not exported.

    _ = errs.ErrOrNil().(*emperror.multiError) // cannot refer to unexported name emperror.multiError

  • Add a drop-in replacement package

    Add a drop-in replacement package

    Add a drop-in replacement package for both standard errors and github.com/pkg/errors.

    Reasons:

    • Cross-package Unwrap support
    • Pre Go 1.12 Is and As support, falling back to the official implementation once 1.13 is released

    Alternatively see:

    • https://github.com/cockroachdb/errors
    • https://github.com/cockroachdb/cockroach/blob/master/docs/RFCS/20190318_error_handling.md
  • Consider adding an error return value to the Handle method

    Consider adding an error return value to the Handle method

    Some handlers may have an error return value (eg. connecting to a remote service failed).

    How should these errors (which cannot be handled by the error handler) handled?

  • Future of emperror

    Future of emperror

    The emperror is good and feature-rich error package, but it has not updated in 2 years. Is it maintained yet? Is there any logr-like error handling module, which is pluginable and emperror can implement it?

  • All test are failing, after building with gollvm

    All test are failing, after building with gollvm

    Hi. Tests are failing, for some reason.

    $ go test ./... go: finding module for package github.com/Workiva/go-datastructures/queue go: finding module for package github.com/jessevdk/go-flags go: finding module for package github.com/grpc-ecosystem/grpc-gateway/runtime go: finding module for package github.com/peterebden/go-cli-init go: finding module for package golang.org/x/crypto/openpgp go: finding module for package github.com/thought-machine/pleasings/java/maven/maven go: finding module for package google.golang.org/grpc go: finding module for package gopkg.in/op/go-logging.v1 go: downloading github.com/jessevdk/go-flags v1.4.0 go: downloading github.com/peterebden/go-cli-init v1.3.1 go: downloading github.com/grpc-ecosystem/grpc-gateway v1.15.0 go: downloading gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 go: downloading github.com/Workiva/go-datastructures v1.0.52 go: downloading golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae go: downloading github.com/thought-machine/pleasings v0.0.0-20200929125113-3a00754cb98a go: found github.com/peterebden/go-cli-init in github.com/peterebden/go-cli-init v1.3.1 go: found github.com/thought-machine/pleasings/java/maven/maven in github.com/thought-machine/pleasings v0.0.0-20200929125113-3a00754cb98a go: found github.com/Workiva/go-datastructures/queue in github.com/Workiva/go-datastructures v1.0.52 go: found github.com/jessevdk/go-flags in github.com/jessevdk/go-flags v1.4.0 go: found gopkg.in/op/go-logging.v1 in gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 go: found github.com/grpc-ecosystem/grpc-gateway/runtime in github.com/grpc-ecosystem/grpc-gateway v1.15.0 go: found google.golang.org/grpc in google.golang.org/grpc v1.32.0 go: found golang.org/x/crypto/openpgp in golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae go: downloading github.com/golang/protobuf v1.3.3 go: downloading github.com/dustin/go-humanize v1.0.0 go: downloading google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884 go: downloading golang.org/x/net v0.0.0-20191002035440-2ec189313ef0 plz-out/gen/pleasings/proto/test/gateway_main.go:14:2: package proto/test/kitten is not in GOROOT (/home/oceanfish81/gollvm_dist/src/proto/test/kitten) plz-out/gen/pleasings/signing/release_signer/main.go:12:2: package signing/release_signer/signer is not in GOROOT (/home/oceanfish81/gollvm_dist/src/signing/release_signer/signer)

    $ go test --- FAIL: TestPanic (0.00s) panic_test.go:11: function name does not match the expected one actual: x2edev..z2femperror.TestPanic expected: TestPanic --- FAIL: TestRecover_ErrorPanic (0.00s) panic_test.go:104: function name does not match the expected one actual: createRecoverFunc..func1 expected: createRecoverFunc.func1 --- FAIL: TestRecover_StringPanic (0.00s) panic_test.go:112: function name does not match the expected one actual: createRecoverFunc..func1 expected: createRecoverFunc.func1 --- FAIL: TestRecover_AnyPanic (0.00s) panic_test.go:120: function name does not match the expected one actual: createRecoverFunc..func1 expected: createRecoverFunc.func1 FAIL exit status 1 FAIL emperror.dev/emperror 0.486s

    I am running tests under

    $ go env && go version GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/home/oceanfis81/.cache/go-build" GOENV="/home/oceanfis81/.config/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="/home/oceanfis81/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/home/oceanfis81/go" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/home/oceanfish81/gollvm_dist" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/home/oceanfish81/gollvm_dist/tools" GCCGO="/home/oceanfish81/gollvm_dist/bin/llvm-goc" AR="ar" CC="/usr/bin/clang" CXX="/usr/bin/clang++" CGO_ENABLED="1" GOMOD="/home/oceanfis81/go_projects/emperror/go.mod" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build061261994=/tmp/go-build -gno-record-gcc-switches -funwind-tables" go version go1.15.2 gollvm LLVM 12.0.0git linux/amd64

    You can reproduce by taking this "release" build of gollvm compiler ("llvm-goc").

    CC @thanm @cherrymui

  • Use `Annotate` instead of `Handle`?

    Use `Annotate` instead of `Handle`?

    Hi! I just stumbled across this repo from visiting: https://github.com/sagikazarmark/modern-go-application?ts=4

    I thought maybe I could provide a suggestion to improve the readability of the code and/or readme and/or provide an opportunity to clarify how the code works. Note that this all stems from the word Handle, and what it usually means in coding, which is "if an error occurs, switch gears and try something else, or gracefully degrade."

    Handle sounds like the error is "dealt-with" in some way and that particular code path after Handle is called, is left without needing to worry about the error, since it has been "handled". However, this doesn't make a lot of sense within the context of the readme where Handle is described as just a way to annotate the error with additional information. So, does it "handle" the error, or does it "annotate" the error?

Common juju errors and functions to annotate errors. Based on juju/errgo

errors import "github.com/juju/errors" The juju/errors provides an easy way to annotate errors without losing the original error context. The exporte

Dec 30, 2022
Linter for errors.Is and errors.As

erris erris is a program for checking that errors are compared or type asserted using go1.13 errors.Is and errors.As functions. Install go get -u gith

Nov 27, 2022
An errors package optimized for the pkg/errors package
An errors package optimized for the pkg/errors package

errors An errors package optimized for the pkg/errors package Use Download and install go get github.com/dobyte/errors API // New Wrapping for errors.

Mar 2, 2022
eris provides a better way to handle, trace, and log errors in Go 🎆

eris Package eris provides a better way to handle, trace, and log errors in Go. go get github.com/rotisserie/eris Why you'll want to switch to eris Us

Dec 29, 2022
A drop-in replacement for Go errors, with some added sugar! Unwrap user-friendly messages, HTTP status code, easy wrapping with multiple error types.
A drop-in replacement for Go errors, with some added sugar! Unwrap user-friendly messages, HTTP status code, easy wrapping with multiple error types.

Errors Errors package is a drop-in replacement of the built-in Go errors package with no external dependencies. It lets you create errors of 11 differ

Dec 6, 2022
A Go (golang) package for representing a list of errors as a single error.

go-multierror go-multierror is a package for Go that provides a mechanism for representing a list of error values as a single error. This allows a fun

Jan 1, 2023
Golang errors with stack trace and source fragments.
Golang errors with stack trace and source fragments.

Golang Errors with Stack Trace and Source Fragments Tired of uninformative error output? Probably this will be more convenient: Example package main

Dec 17, 2022
Hierarchical errors reporting done right in Golang

Hierarchical errors made right Hate seeing error: exit status 128 in the output of programs without actual explanation what is going wrong? Or, maybe,

Nov 9, 2021
Go tool to wrap and fix errors with the new %w verb directive
Go tool to wrap and fix errors with the new %w verb directive

errwrap Wrap and fix Go errors with the new %w verb directive. This tool analyzes fmt.Errorf() calls and reports calls that contain a verb directive t

Nov 10, 2022
Golang errors with stacktrace and context

merry Add context to errors, including automatic stack capture, cause chains, HTTP status code, user messages, and arbitrary values. The package is la

Nov 19, 2022
harvest Go errors with ease

Pears Harvest Go Errors with Ease Introduction Pears helps reduce the boilerplate and ensure correctness for common error-handling scenarios: Panic re

Apr 25, 2021
SupErr -- Go stdlib errors with super powers

superr SupErr -- Go stdlib errors with super powers. Pronounced super with a French accent :D Build a stack of errors compatible with Go stdlib and er

Nov 15, 2022
Package semerr helps to work with errors in Golang.
Package semerr helps to work with errors in Golang.

semerr Package semerr helps to work with errors in Golang. Const error An error that can be defined as const. var errMutable error = errors.New("mutab

Oct 30, 2022
A Nostress Errors Package For Golang

A Nostress Errors Package For Golang

Nov 2, 2021
Simple Go library for typed errors creation

go-typed-errors Why this repo was created? Main reason was to create additional methods for better error typing support. Why not to use errors.As and

Nov 5, 2021
Simple Go library for typed const errors creation

go-errors Why this repo was created? Main reason was to create additional methods for better error typing support. Features Errors as constants errors

Nov 5, 2021
This project is for parsing Artifactory logs for errors

hello-frog About this plugin This plugin is a template and a functioning example for a basic JFrog CLI plugin. This README shows the expected structur

Nov 30, 2021
Go package for errors with chained stack traces

errstack: Go errors with chained stack traces errstack is a Go package for creating errors with stack traces. It is heavily inspired by github.com/pkg

Nov 27, 2021
A Go package providing errors with a stack trace Read-only

Errors with a stack trace A Go package providing errors with a stack trace. Features: Based of github.com/pkg/errors with similar API, addressing many

Sep 23, 2022