All Projects → morikuni → Failure

morikuni / Failure

Licence: mit
failure is a utility package for handling application errors.

Programming Languages

go
31211 projects - #10 most used programming language
golang
3204 projects

Projects that are alternatives of or similar to Failure

rust-error-handle
detail rust error handle
Stars: ✭ 47 (-74.87%)
Mutual labels:  error-handling, error
Thoth
An Error Logger for Go
Stars: ✭ 22 (-88.24%)
Mutual labels:  error-handling, error
go-errors
Flexible, general-purpose error handling for Go.
Stars: ✭ 17 (-90.91%)
Mutual labels:  error-handling, error
custom-exception-middleware
Middleware to catch custom or accidental exceptions
Stars: ✭ 30 (-83.96%)
Mutual labels:  error-handling, error
Bugsnag Go
Automatic panic monitoring for Go and Go web frameworks, like negroni, gin, and revel
Stars: ✭ 155 (-17.11%)
Mutual labels:  error-handling, error
failure
An error handling package for Go.
Stars: ✭ 24 (-87.17%)
Mutual labels:  error-handling, error
Error Overlay Webpack Plugin
Catch errors with style 💥✨
Stars: ✭ 821 (+339.04%)
Mutual labels:  error-handling, error
Emperror
The Emperor takes care of all errors personally
Stars: ✭ 201 (+7.49%)
Mutual labels:  error-handling, error
Go Errortree
Go library for handling errors organized as a tree
Stars: ✭ 59 (-68.45%)
Mutual labels:  error-handling, error
Bugsnag Node
[DEPRECATED] Please upgrade to our Universal JS notifier "@bugsnag/js" • https://github.com/bugsnag/bugsnag-js
Stars: ✭ 48 (-74.33%)
Mutual labels:  error-handling, error
koa-better-error-handler
A better error-handler for Lad and Koa. Makes `ctx.throw` awesome (best used with koa-404-handler)
Stars: ✭ 51 (-72.73%)
Mutual labels:  error-handling, error
Swift Error Handler
Error handling library for Swift
Stars: ✭ 172 (-8.02%)
Mutual labels:  error-handling, error
TrackJS-Node
TrackJS Error Monitoring agent for NodeJS
Stars: ✭ 26 (-86.1%)
Mutual labels:  error-handling, error
ErrorLayout
Simple layout to show custom error toast with animation
Stars: ✭ 13 (-93.05%)
Mutual labels:  error-handling, error
Human Signals
Human-friendly process signals
Stars: ✭ 223 (+19.25%)
Mutual labels:  error-handling, error
Log Process Errors
Show some ❤️ to Node.js process errors
Stars: ✭ 424 (+126.74%)
Mutual labels:  error-handling, error
Make Error Cause
Make your own nested errors
Stars: ✭ 36 (-80.75%)
Mutual labels:  error-handling, error
Extensible Custom Error
JavaScript extensible custom error that can take a message and/or an Error object
Stars: ✭ 64 (-65.78%)
Mutual labels:  error-handling, error
Graphql Errors
Simple error handler for GraphQL Ruby ❗️
Stars: ✭ 170 (-9.09%)
Mutual labels:  error-handling, error
Ignition
A beautiful error page for Laravel apps
Stars: ✭ 1,885 (+908.02%)
Mutual labels:  error

failure

CircleCI Go Reference Go Report Card codecov

Package failure provides errors utilities for your application errors.

  • Automatically generate awesome err.Error message for developers.
  • Flexible error messages for end users.
  • Powerful and readable stack trace.
  • Error context, such as function parameter, with key-value data.
  • Extensible error chain.

Usage

At first, define error codes for your application.

const (
	NotFound failure.StringCode = "NotFound"
	InvalidArgument failure.StringCode = "InvalidArgument"
	Internal failure.StringCode = "Internal"
)

Using failure.New, return an error with error code.

return failure.New(NotFound)

Handle the error with failure.Is and translate it into another error code with failure.Translate.

if failure.Is(err, NotFound) {
	return failure.Translate(err, Internal)
}

If you want to just return the error, use failure.Wrap.

if err != nil {
	return failure.Wrap(err)
}

An error context and message for end user can be attached.

func Foo(a, b string) error {
	return failure.New(InvalidArgument, 
		failure.Context{"a": a, "b": b},
		failure.Message("Given parameters are invalid!!"),
	)
}

Awesome error message for developers.

func main() {
	err := Bar()
	fmt.Println(err)
	fmt.Println("=====")
	fmt.Printf("%+v\n", err)
}

func Bar() error {
	err := Foo("hello", "world")
	if err != nil {
		return failure.Wrap(err)
	}
	return nil
}
main.Bar: main.Foo: a=hello b=world: Given parameters are invalid!!: code(InvalidArgument)
=====
[main.Bar] /tmp/sandbox615088634/prog.go:25
[main.Foo] /tmp/sandbox615088634/prog.go:31
    a = hello
    b = world
    message("Given parameters are invalid!!")
    code(InvalidArgument)
[CallStack]
    [main.Foo] /tmp/sandbox615088634/prog.go:31
    [main.Bar] /tmp/sandbox615088634/prog.go:23
    [main.main] /tmp/sandbox615088634/prog.go:16
    [runtime.main] /usr/local/go-faketime/src/runtime/proc.go:204
    [runtime.goexit] /usr/local/go-faketime/src/runtime/asm_amd64.s:1374

package.FunctionName like main.Bar and main.Foo is automatically added to error message. With %+v format, it prints the detailed error chain + the call stack of the first error.

Full Example for HTTP Server

Try it on The Go Playground!

Or click on the below to see the code.

package main

import (
	"fmt"
	"io"
	"net/http"
	"net/http/httptest"
	"net/http/httputil"

	"github.com/morikuni/failure"
)

// error codes for your application.
const (
	NotFound  failure.StringCode = "NotFound"
	Forbidden failure.StringCode = "Forbidden"
)

func GetACL(projectID, userID string) (acl interface{}, e error) {
	notFound := true
	if notFound {
		return nil, failure.New(NotFound,
			failure.Context{"project_id": projectID, "user_id": userID},
		)
	}
	return nil, failure.Unexpected("unexpected error")
}

func GetProject(projectID, userID string) (project interface{}, e error) {
	_, err := GetACL(projectID, userID)
	if err != nil {
		if failure.Is(err, NotFound) {
			return nil, failure.Translate(err, Forbidden,
				failure.Message("no acl exists"),
				failure.Context{"additional_info": "hello"},
			)
		}
		return nil, failure.Wrap(err)
	}
	return nil, nil
}

func Handler(w http.ResponseWriter, r *http.Request) {
	_, err := GetProject(r.FormValue("project_id"), r.FormValue("user_id"))
	if err != nil {
		HandleError(w, err)
		return
	}
}

func getHTTPStatus(err error) int {
	c, ok := failure.CodeOf(err)
	if !ok {
		return http.StatusInternalServerError
	}
	switch c {
	case NotFound:
		return http.StatusNotFound
	case Forbidden:
		return http.StatusForbidden
	default:
		return http.StatusInternalServerError
	}
}

func getMessage(err error) string {
	msg, ok := failure.MessageOf(err)
	if ok {
		return msg
	}
	return "Error"
}

func HandleError(w http.ResponseWriter, err error) {
	w.WriteHeader(getHTTPStatus(err))
	io.WriteString(w, getMessage(err))

	fmt.Println("============ Error ============")
	fmt.Printf("Error = %v\n", err)

	code, _ := failure.CodeOf(err)
	fmt.Printf("Code = %v\n", code)

	msg, _ := failure.MessageOf(err)
	fmt.Printf("Message = %v\n", msg)

	cs, _ := failure.CallStackOf(err)
	fmt.Printf("CallStack = %v\n", cs)

	fmt.Printf("Cause = %v\n", failure.CauseOf(err))

	fmt.Println()
	fmt.Println("============ Detail ============")
	fmt.Printf("%+v\n", err)
	// [main.GetProject] /go/src/github.com/morikuni/failure/example/main.go:36
	//     message("no acl exists")
	//     additional_info = hello
	//     code(Forbidden)
	// [main.GetACL] /go/src/github.com/morikuni/failure/example/main.go:21
	//     project_id = 123
	//     user_id = 456
	//     code(NotFound)
	// [CallStack]
	//     [main.GetACL] /go/src/github.com/morikuni/failure/example/main.go:21
	//     [main.GetProject] /go/src/github.com/morikuni/failure/example/main.go:33
	//     [main.Handler] /go/src/github.com/morikuni/failure/example/main.go:47
	//     [http.HandlerFunc.ServeHTTP] /usr/local/go/src/net/http/server.go:1964
	//     [http.(*ServeMux).ServeHTTP] /usr/local/go/src/net/http/server.go:2361
	//     [http.serverHandler.ServeHTTP] /usr/local/go/src/net/http/server.go:2741
	//     [http.(*conn).serve] /usr/local/go/src/net/http/server.go:1847
	//     [runtime.goexit] /usr/local/go/src/runtime/asm_amd64.s:1333
}

func main() {
	req := httptest.NewRequest(http.MethodGet, "/?project_id=aaa&user_id=111", nil)
	rec := httptest.NewRecorder()
	Handler(rec, req)

	res, _ := httputil.DumpResponse(rec.Result(), true)
	fmt.Println("============ Dump ============")
	fmt.Println(string(res))
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].