Code Monkey home page Code Monkey logo

errors's Introduction

errors

Golang errors implementation with stack traces and client/server errors.

Build Status Coverage Status GoDoc

Goal, design principles

  • implement the standard errors interface
  • type safe, no magic, no side effects
  • offer stack traces
  • allow decorating errors when passing back along the call chain (add debug info where it is available)
  • do not leak implementation details to untrusted clients
  • allow type-checking of errors (package level error types in dependant packages)

Experimental

Checking for errors all the time is pain in the ass. Instead of returning them all the time as the last argument, call panic(Err) instead and catch them with Catch(). There is a small performance penalty (~0.2us) of using Catch, but when using at the top of a call-chain, it is offset by the reduced overhead of not needing to check if Err != nil { .. } all the time. Run the benchmarks on your own machine, on my system the speed of the 2 ways equaled around 100 function calls. So, if there are more than 100 func calls inside the call of Catch, it starts to improve speed instead of degrading it. In the order of above 1000 calls, function calling overhead dropped by 30%.

Note that using panic() is not idiomatic go. Yet if I can write 50% less code, that is easier to read, and doing it is overall way more enjoyable, I'm willing to explore new grounds. The rules of what is idiomatic tend to change over time anyway.

Examples

Example - simple client error

var ErrInvalidPassword = errors.Type("ERR_INVALID_PASSWORD")

func ReturnError(pw string) (errors.Error) {
	return ErrInvalidPassword.ClientError("invalid password")
}

Example - returning error message to client

Err := ReturnError(password)
if Err != nil {
	fmt.Println(Err)
	// Prints "invalid password"
}

Example - checking error agains type

Err := ReturnError(password)
if Err.Is(ErrInvalidPassword) {
	// ...
}

Example - client error with debug message

var ErrPwTooShort = errors.Type("ErrPwTooShort")
const MIN_LEN_PW = 8

func PasswordTooShort(pw string) (errors.Error) {
	if len(pw) < MIN_LEN_PW {
		return ErrPwTooShort.ClientErrorf("password too short [%v], minimum [%v] chars required", len(pw), MIN_LEN_PW)
	}
	return nil
}

Example - server error with debug message

var ErrFooNotBar = errors.Type("ErrFooNotBar")

func ExpectBar(foo string) (errors.Error) {
	if foo != "bar" {
		return ErrFooNotBar.ServerErrorf("unexpected foo value [%v]", foo)
	}
	return nil
}

Example - print debug info for trusted client

Err := ExpectBar("oh")
if Err != nil {
	// Prints stack trace with error message
	fmt.Println(Err.Debug())
	// Err.Error() prints debug message for untrusted client "internal server error"
}

Example debug message:

client error:

fn:  main.main
src: /home/user/project/example/clientError.go:21
cli: errors message

fn:  runtime.main
src: /usr/local/go/src/pkg/runtime/proc.c:255

fn:  runtime.goexit
src: /usr/local/go/src/pkg/runtime/proc.c:1445

Example - decorate error object with custom client/server messages

var ErrDecorate := errors.Type("ErrDecorate")
func ReturnOriginalError() (errors.Error) {
	return ErrDecorate.ServerError("original error message")
}
func ReturnDecoratedError() (errors.Error) {
	Err := ReturnOriginalError()
	Err.ClientNote("custom error decoration for untrusted clients")
	Err.ServerNotef("error decoration for [%v]", "debugging")
	return Err
}

The above may return a debug message like:

server error:

fn:  main.ReturnOriginalError
src: /home/user/project/example/clientError.go:21
srv: original error message

fn:  main.ReturnDecoratedError
src: /home/user/project/example/clientError.go:24
cli: custom error decoration for untrusted clients
srv: error decoration for [debugging]

fn:  main.main
src: /home/user/project/example/clientError.go:41

fn:  runtime.main
src: /usr/local/go/src/pkg/runtime/proc.c:255

fn:  runtime.goexit
src: /usr/local/go/src/pkg/runtime/proc.c:1445

Example - log internal errors

Err := doSomething()
if Err != nil && Err.IsServerError() {
	// Log internal error, notify sys admin
}

Example - temporarily turn client errors into debug messages

errors.Debug = true
// From here on, Err.Error() redirects to Err.Debug()
// Warning: use for local debugging only

Example - panic instead of returning errors, catch them

var ErrPanic = errors.Type("ErrPanic")

func FailDoingSg() {
	panic(ErrPanic.ClientError("panicing!"))
}

func CatchingPanic() (errors.Error) {
	return Catch(func() {
		FailDoingSg()
	})
}

Installation

To install according to your $GOPATH:

$ go get github.com/zupa-hu/errors

Import the errors package

import "github.com/zupa-hu/errors"

Testing

run go test.

errors's People

Contributors

zupa-hu avatar

Stargazers

abdul dakkak avatar

Watchers

James Cloos avatar  avatar

errors's Issues

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.