errmsg

package module
v0.0.0-...-91e6e90 Latest Latest
Warning

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

Go to latest
Published: Jul 31, 2019 License: MIT Imports: 7 Imported by: 6

README

errmsg

structured error representation

Feature

  • structured error
  • classify error base on status
  • Built-in 17 error status
  • translate error status to HTTP status and grpc codes, etc
  • translate error information to JSON body and grpc status, etc
  • wrap location where the error occurred
  • integrated zap and logrus

Usage

	errmsg.SetFlags(errmsg.FstdFlag | errmsg.Fshortfile)

	err := errors.New("this is a test")
	err = errmsg.Wrap(errmsg.ErrUnavailable, err)

	// Output: this is a test
	fmt.Println(err.Error())

	// Output: status: Unavailable, message: this is a test, file:???.go, line: ???
	fmt.Println(err.String())

	// Output: {"status":"Unavailable","message":"this is a test"}
	s := json.Marshal(err)

	// Output: 503
	fmt.Println(errmsg.HTTPStatus(err))

	// Output: Unavailable
	fmt.Println(errmsg_grpc.Code(err))
	// Output: rpc error: code = Unavailable desc = this is a test
	fmt.Println(errmsg_grpc.Status(err).Err())

	zapLogger := zap.NewExample()
	// Output: ERROR   ???.go:?? error information        {"status": "Unavailable", "message": "this is a test", "file": "???.go", "line": ??}
	zapLogger.Error("error information", errmsg_zap.Fields(err)...)

	logrusLogger := logrus.New()
	// Output: time="... ..." level=error msg="error information" file=???.go line=?? message="this is a test" status=Unavailable
	logrusLogger.WithFields(errmsg_logrus.Fields(err)).Error("error information")

Documentation

Index

Examples

Constants

View Source
const (
	// FstdFlag just wrap error status and message
	FstdFlag = 1 << iota

	// Fshortfile capture file name and line number, overrides Flongfile
	Fshortfile

	// Flongfile capture full file path and line number
	Flongfile
)

Variables

View Source
var (
	// NoError No error
	NoError = errors.New("OK")

	// NoErrMsg No error
	NoErrMsg = &ErrMsg{error: NoError, Status: ErrOK}
)

Functions

func BindErrStatus

func BindErrStatus(status ErrStatus, name string)

BindErrStatus Bind custom error status with name.

func BindHTTPStatus

func BindHTTPStatus(status ErrStatus, httpStatus int)

BindHTTPStatus Bind HTTP status with error status

func HTTPStatus

func HTTPStatus(err error) int

HTTPStatus Get HTTP status by error status

Example (Zap)
package main

import (
	"encoding/json"
	"errors"
	"io/ioutil"
	"net/http"
	"net/http/httptest"

	"github.com/wencan/errmsg"
	errmsg_zap "github.com/wencan/errmsg/logging/zap"
	"go.uber.org/zap"
)

func getError() error {
	return errors.New("this is a test")
}

func doSomeThing() error {
	err := getError()
	if err != nil {
		// Wrap error
		return errmsg.WrapError(errmsg.ErrUnavailable, err)
	}
	return nil
}

type Handler struct {
	Logger *zap.Logger
}

func (handler *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	err := doSomeThing()
	if err != nil {
		// log
		
Output:

{"level":"error","msg":"doSomeThing fail","status":"Unavailable","message":"this is a test","file":"example_http_test.go","line":23}
{"level":"info","msg":"503 Service Unavailable","statusCode":503,"body":"{\"message\":\"this is a test\",\"status\":\"Unavailable\"}"}

func SetFlags

func SetFlags(flag int)

SetFlags set global flags

Types

type ErrMsg

type ErrMsg struct {
	Status  ErrStatus `json:"-"`
	Message string    `json:"message"`

	File string `json:"-"`
	Line int    `json:"-"`

	Stack string `json:"stack,omitempty"`
	// contains filtered or unexported fields
}

ErrMsg error detail

func Unwrap

func Unwrap(err error) *ErrMsg

Unwrap Unwrap a error to *ErrMsg. return a NoErrMsg if err is nil; return a ErrMsg with unknown status if err not is instance of ErrMsg.

func WrapError

func WrapError(status ErrStatus, err error) *ErrMsg

WrapError Wrap a error object, attach error detail.

Example
package main

import (
	"encoding/json"
	"errors"
	"fmt"

	"github.com/wencan/errmsg"
)

func main() {
	errmsg.SetFlags(errmsg.FstdFlag | errmsg.Fshortfile)
	defer errmsg.SetFlags(errmsg.FstdFlag)

	getError := func() error {
		return errors.New("this is a test")
	}

	doSomeThing := func() error {
		err := getError()
		if err != nil {
			// Wrap error
			return errmsg.WrapError(errmsg.ErrUnavailable, err)
		}
		return nil
	}

	err := doSomeThing()
	fmt.Println("Error:", err)

	data, e := json.Marshal(err)
	if e != nil {
		fmt.Println(e)
		return
	}
	fmt.Println("Json:", string(data))

	errMsg := err.(*errmsg.ErrMsg)
	fmt.Println("File:", errMsg.File)
	fmt.Println("Line:", errMsg.Line)

}
Output:

Error: this is a test
Json: {"message":"this is a test","status":"Unavailable"}
File: example_test.go
Line: 30

func WrapErrorWithStack

func WrapErrorWithStack(status ErrStatus, err error) *ErrMsg

WrapErrorWithStack Wrap a error object, attach error detail and call stack

func (*ErrMsg) Error

func (errMsg *ErrMsg) Error() string

Error implement error.

func (*ErrMsg) MarshalJSON

func (errMsg *ErrMsg) MarshalJSON() ([]byte, error)

MarshalJSON Implement json.Marshaler. Provide to the kit/transport.DefaultErrorEncoder.

func (*ErrMsg) StatusCode

func (errMsg *ErrMsg) StatusCode() int

StatusCode Implement kit/transport/http.StatusCoder

func (*ErrMsg) String

func (errMsg *ErrMsg) String() string

String implement Stringer

func (*ErrMsg) UnmarshalJSON

func (errMsg *ErrMsg) UnmarshalJSON(data []byte) error

UnmarshalJSON Implement json.Unmarshaler.

type ErrStatus

type ErrStatus uint16

ErrStatus error status

const (
	// ErrOK No error.
	ErrOK ErrStatus = iota

	// ErrInvalidArgument Client specified an invalid argument.
	// Check error message and error details for more information.
	ErrInvalidArgument

	// ErrFailedPrecondition Request can not be executed in the current system state,
	// such as deleting a non-empty directory.
	ErrFailedPrecondition

	// ErrOutOfRange Client specified an invalid range.
	ErrOutOfRange

	// ErrUnauthenticated Request not authenticated due to missing,
	// invalid, or expired OAuth token.
	ErrUnauthenticated

	// ErrPermissionDenied Client does not have sufficient permission.
	// This can happen because the OAuth token does not have the right scopes,
	// the client doesn't have permission,
	// or the API has not been enabled for the client project.
	ErrPermissionDenied

	// ErrNotFound A specified resource is not found,
	// or the request is rejected by undisclosed reasons,
	// such as whitelisting.
	ErrNotFound

	// ErrAborted Concurrency conflict,
	// such as read-modify-write conflict.
	ErrAborted

	// ErrAlreadyExists The resource that a client tried to create already exists.
	ErrAlreadyExists

	// ErrResourceExhausted Either out of resource quota or reaching rate limiting.
	// The client should look for google.rpc.QuotaFailure error detail for more information.
	ErrResourceExhausted

	// ErrCancelled Request cancelled by the client.
	ErrCancelled

	// ErrDataLoss Unrecoverable data loss or data corruption.
	// The client should report the error to the user.
	ErrDataLoss

	// ErrUnknown Unknown server error. Typically a server bug.
	ErrUnknown

	// ErrInternal Internal server error. Typically a server bug.
	ErrInternal

	// ErrNotImplemented API method not implemented by the server.
	ErrNotImplemented

	// ErrUnavailable Service unavailable. Typically the server is down.
	ErrUnavailable

	// ErrDeadlineExceeded  Request deadline exceeded.
	// This will happen only if the caller sets a deadline that is shorter than the method's default deadline
	// (i.e. requested deadline is not enough for the server to process the request) and the request did not finish within the deadline.
	ErrDeadlineExceeded
)

func FromStatusName

func FromStatusName(statusName string) ErrStatus

FromStatusName Convert status name to status value

func (ErrStatus) String

func (status ErrStatus) String() string

Directories

Path Synopsis
logging
zap

Jump to

Keyboard shortcuts

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