reguerr

package module
v0.7.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 12, 2021 License: Apache-2.0 Imports: 4 Imported by: 0

README

reguerr

reguerr - Code generator for systematic error handling

Abstract

reguerr helps with systematic error handling.

In order to facilitate the handling of system failure, you can set the error code to identify the error in reguerr and the log level and response code associated with it.

Installation

go get -u gitlab.com/osaki-lab/reguerr/cmd/reguerr

Options

>reguerr -h

Usage:
  reguerr [command]

Available Commands:
  generate    generate reguerr code
  help        Help about any command
  validate    validate input file

Flags:
  -h, --help   help for reguerr

generate command is main function in reguerr.

>reguerr generate -h
generate reguerr code

Usage:
  reguerr generate [flags]

Flags:
      --defaultErrorLevel string   change default log level(Trace,Debug,Info,Warn,Error,Fatal)
      --defaultStatusCode int      change default status code (default -1)
  -f, --file string                input go file
  -h, --help                       help for generate

Usage

# target file
cat <<EOF > example.go
package example

import (
	"gitlab.com/osaki-lab/reguerr"
)

var (
	// No message arguments
	PermissionDeniedErr = reguerr.New("1001", "permission denied").Build()

	// One message arguments
	UpdateConflictErr = reguerr.New("1002", "other user updated: key=%s").Build()

	// Message arguments with label
	InvalidInputParameterErr = reguerr.New("1003", "invalid input parameter: %v").
		Label(0,"payload", map[string]interface{}{}).
		Build()
)
EOF

# START reguerr
./reguerr generate -f example.go

Output is bellow format.

// Code generated by reguerr; DO NOT EDIT.
package example

import (
	"gitlab.com/osaki-lab/reguerr"
)

func NewPermissionDeniedErr(err error) *reguerr.Error {
	return PermissionDeniedErr.WithError(err)
}

func IsPermissionDeniedErr(err error) bool {
	var cerr *reguerr.Error
	if as := errors.As(err, &cerr); as {
		if cerr.Code() == PermissionDeniedErr.Code() {
			return true
		}
	}
	return false
}

func NewUpdateConflictErr(err error, arg1 interface{}) *reguerr.Error {
	return UpdateConflictErr.WithError(err).WithArgs(arg1)
}

func IsUpdateConflictErr(err error) bool {
	var cerr *reguerr.Error
	if as := errors.As(err, &cerr); as {
		if cerr.Code() == UpdateConflictErr.Code() {
			return true
		}
	}
	return false
}

func NewInvalidInputParameterErr(err error, payload map[string]interface{}) *reguerr.Error {
	return InvalidInputParameterErr.WithError(err).WithArgs(payload)
}

func IsInvalidInputParameterErr(err error) bool {
	var cerr *reguerr.Error
	if as := errors.As(err, &cerr); as {
		if cerr.Code() == InvalidInputParameterErr.Code() {
			return true
		}
	}
	return false
}

Then reguerr also generated markdown table.

CODE NAME LOGLEVEL STATUSCODE FORMAT
1001 PermissionDeniedErr Error 500 permission denied
1002 UpdateConflictErr Error 500 other user updated: key=%s
1003 InvalidInputParameterErr Error 500 invalid input parameter: %v

If you want to see more examples, you can get example.

Use Case reguerr

The output location of the error log and the switching process of the response status code are aggregated.

package example

import (
	"fmt"
	"github.com/rs/zerolog"
	"github.com/rs/zerolog/log"
	"gitlab.com/osaki-lab/reguerr"
	"net/http"
)

func UserHandleFunc(w http.ResponseWriter, r *http.Request) {
	if err := somethingUserOperation("id1"); err != nil {
		errorLog(err)
		w.WriteHeader(httpStatus(err))
		return
	}
	w.WriteHeader(http.StatusOK)
}

func errorLog(err error) {
	rerr, ok := reguerr.ErrorOf(err)
	if ok {
		level, err := zerolog.ParseLevel(rerr.Level().String())
		if err != nil {
			log.Error().Str("code", rerr.Code()).Msgf(rerr.Error())
		} else {
			log.WithLevel(level).Str("code", rerr.Code()).Msgf(rerr.Error())
		}
		return
	}
	log.Printf("unexpected error: %v\n", err)
}

func httpStatus(err error) int {
	code, ok := reguerr.StatusOf(err)
	if ok {
		return code
	} else {
		return http.StatusInternalServerError
	}
}

func somethingUserOperation(key string) error {
	// some operation for user
	return NewNotFoundOperationIDErr(fmt.Errorf("key=%v", key))
}

License

Apache License Version 2.0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	DefaultErrorLevel = Error
	DefaultStatusCode = 500
)

Functions

func CodeOf added in v0.6.1

func CodeOf(err error) (string, bool)

func StatusOf added in v0.6.1

func StatusOf(err error) (int, bool)

Types

type Builder added in v0.5.1

type Builder struct {
	// contains filtered or unexported fields
}

func New

func New(code, format string) *Builder

func (*Builder) Build added in v0.5.1

func (b *Builder) Build() *ReguError

func (*Builder) Debug added in v0.7.1

func (b *Builder) Debug() *Builder

func (*Builder) DisableError added in v0.5.1

func (b *Builder) DisableError() *Builder

func (*Builder) Error added in v0.7.1

func (b *Builder) Error() *Builder

func (*Builder) Fatal added in v0.7.1

func (b *Builder) Fatal() *Builder

func (*Builder) Info added in v0.7.1

func (b *Builder) Info() *Builder

func (*Builder) Label added in v0.5.1

func (b *Builder) Label(index int, name string, goType interface{}) *Builder

func (*Builder) Trace added in v0.7.1

func (b *Builder) Trace() *Builder

func (*Builder) Warn added in v0.7.1

func (b *Builder) Warn() *Builder

func (*Builder) WithStatusCode added in v0.5.1

func (b *Builder) WithStatusCode(statusCode int) *Builder

type Code added in v0.6.1

type Code string

type Level

type Level int

Level represents error level that developer can handle error depending on each variable

const (
	Trace Level = iota + 1
	Debug
	Info
	Warn
	Error
	Fatal
	Unknown
)

func LevelOf added in v0.6.1

func LevelOf(err error) (Level, bool)

func NewLevel added in v0.6.1

func NewLevel(s string) (Level, error)

func (Level) Equals added in v0.6.1

func (i Level) Equals(arg Level) bool

func (Level) String

func (i Level) String() string

type ReguError added in v0.6.1

type ReguError struct {
	// contains filtered or unexported fields
}

func ErrorOf added in v0.6.1

func ErrorOf(err error) (*ReguError, bool)

func (*ReguError) Code added in v0.6.1

func (e *ReguError) Code() string

func (*ReguError) Error added in v0.6.1

func (e *ReguError) Error() string

func (*ReguError) IsDebugLevel added in v0.6.1

func (e *ReguError) IsDebugLevel() bool

func (*ReguError) IsErrorLevel added in v0.6.1

func (e *ReguError) IsErrorLevel() bool

func (*ReguError) IsFatalLevel added in v0.6.1

func (e *ReguError) IsFatalLevel() bool

func (*ReguError) IsInfoLevel added in v0.6.1

func (e *ReguError) IsInfoLevel() bool

func (*ReguError) IsTraceLevel added in v0.6.1

func (e *ReguError) IsTraceLevel() bool

func (*ReguError) IsWarnLevel added in v0.6.1

func (e *ReguError) IsWarnLevel() bool

func (*ReguError) Level added in v0.6.1

func (e *ReguError) Level() Level

func (*ReguError) StatusCode added in v0.6.1

func (e *ReguError) StatusCode() int

func (*ReguError) Unwrap added in v0.7.1

func (e *ReguError) Unwrap() error

func (*ReguError) WithArgs added in v0.6.1

func (e *ReguError) WithArgs(args ...interface{}) *ReguError

func (*ReguError) WithError added in v0.6.1

func (e *ReguError) WithError(err error) *ReguError

Directories

Path Synopsis
cmd
generated by reguerr; DO NOT EDIT
generated by reguerr; DO NOT EDIT

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL