Skip to content

future-architect/reguerr

Repository files navigation

logo

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 install gitlab.com/future-architect/reguerr/cmd/reguerr@latest

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/future-architect/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/future-architect/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/future-architect/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

About

reguerr - Code generator for systematic error handling

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages