Coder Social home page Coder Social logo

emperror / emperror Goto Github PK

View Code? Open in Web Editor NEW
341.0 4.0 19.0 973 KB

The Emperor takes care of all errors personally

Home Page: https://emperror.dev/emperror

License: MIT License

Go 96.30% Starlark 0.22% Shell 3.49%
go golang error-handling error-handler error-monitoring error-reporting error

emperror's Introduction

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

emperror's People

Contributors

dionysius avatar sagikazarmark avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

emperror's Issues

Easier use of context values

It would be nice to have options to get map from context values. Exporting the keyvals package could be one solution.

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`?

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?

Add context handler

Add a handler that accepts a context.Context and extracts error context from it.

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?

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.