当前位置:   article > 正文

golang封装业务err(结合iris)

golang封装业务err(结合iris)

golang封装业务err

我们有时在web开发时,仅凭httpStatus以及msg是不方便维护和体现我们的业务逻辑的。所以就需要封装我们自己的业务错误。

  • 自定义biz_err
  • 维护err map:errorResponseMap、errorHttpStatusMap

注意:本文主要以演示为主,主要是让大家熟悉封装自定义错误的思路,故而封装的较为简单。大家可根据自己公司需求来进行拓展。

代码仓库地址:https://github.com/ziyifast/ziyifast-code_instruction

项目结构:
在这里插入图片描述

1 err:自定义err,重写打印格式等

1.1 biz_err_demo/error/zerr/errors.go:new方法

  1. 重写控制台打印格式
  2. 封装new方法
  • DefaultBizWrap:不含原始err
  • BizWrap:包含原始err
package zerr

import (
	"errors"
	"fmt"
	"io"
)

func New(message string) error {
	return &fundamental{
		msg:   message,
		stack: callers(),
	}
}

func Errorf(format string, args ...interface{}) error {
	return &fundamental{
		msg:   fmt.Sprintf(format, args...),
		stack: callers(),
	}
}

type fundamental struct {
	msg string
	*stack
}

func (f *fundamental) Error() string { return f.msg }

func (f *fundamental) Format(s fmt.State, verb rune) {
	switch verb {
	case 'v':
		if s.Flag('+') {
			io.WriteString(s, f.msg)
			f.stack.Format(s, verb)
			return
		}
		fallthrough
	case 's':
		io.WriteString(s, f.msg)
	case 'q':
		fmt.Fprintf(s, "%q", f.msg)
	}
}

func WithStack(err error) error {
	if err == nil {
		return nil
	}
	return &withStack{
		err,
		callers(),
	}
}

type withStack struct {
	error
	*stack
}

func (w *withStack) Cause() error { return w.error }

func (w *withStack) Format(s fmt.State, verb rune) {
	switch verb {
	case 'v':
		if s.Flag('+') {
			fmt.Fprintf(s, "%+v", w.Cause())
			w.stack.Format(s, verb)
			return
		}
		fallthrough
	case 's':
		io.WriteString(s, w.Error())
	case 'q':
		fmt.Fprintf(s, "%q", w.Error())
	}
}

func Wrap(err error, message string) error {
	if err == nil {
		return nil
	}
	err = &withMessage{
		cause: err,
		msg:   message,
	}
	return &withStack{
		err,
		callers(),
	}
}

func Trace(err error) error {
	return Wrapf(err, "")
}

func Wrapf(err error, format string, args ...interface{}) error {
	if err == nil {
		return nil
	}
	err = &withMessage{
		cause: err,
		msg:   fmt.Sprintf(format, args...),
	}
	return &withStack{
		err,
		callers(),
	}
}

func WithMessage(err error, message string) error {
	if err == nil {
		return nil
	}
	return &withMessage{
		cause: err,
		msg:   message,
	}
}

func WithMessagef(err error, format string, args ...interface{}) error {
	if err == nil {
		return nil
	}
	return &withMessage{
		cause: err,
		msg:   fmt.Sprintf(format, args...),
	}
}

type withMessage struct {
	cause error
	msg   string
}

func (w *withMessage) Error() string {
	return w.msg + ": " + w.cause.Error()
}

func (w *withMessage) Cause() error {
	return w.cause
}

func (w *withMessage) Format(s fmt.State, verb rune) {
	switch verb {
	case 'v':
		if s.Flag('+') {
			fmt.Fprintf(s, "%+v\n", w.Cause())
			io.WriteString(s, w.msg)
			return
		}
		fallthrough
	case 's', 'q':
		io.WriteString(s, w.Error())
	}
}

func Cause(err error) error {
	type causer interface {
		Cause() error
	}

	for err != nil {
		cause, ok := err.(causer)
		if !ok {
			break
		}
		err = cause.Cause()
	}
	return err
}

func WithCode(err error, code string) error {
	if err == nil {
		return nil
	}
	return &ErrWrap{
		cause: err,
		code:  code,
	}
}

func WithCodef(err error, format string, args ...interface{}) error {
	if err == nil {
		return nil
	}
	return &ErrWrap{
		cause: err,
		code:  fmt.Sprintf(format, args...),
	}
}

type ErrWrap struct {
	cause error
	code  string
	vars  []string
}

func (w *ErrWrap) Vars() []string {
	return w.vars
}

func (w *ErrWrap) Code() string {
	return w.code
}

func (w *ErrWrap) Error() string {
	var msg string
	if w.cause != nil {
		msg += w.cause.Error()
	}
	return msg
}

func (w *ErrWrap) Cause() error {
	return w.cause
}

// Format rewrite format
func (w *ErrWrap) Format(s fmt.State, verb rune) {
	switch verb {
	case 'v':
		if s.Flag('+') {
			fmt.Fprintf(s, "%+v\n", w.Cause())
			io.WriteString(s, "BizCode=["+string(w.code)+"]")
			return
		}
		fallthrough
	case 's', 'q':
		io.WriteString(s, w.Error())
	}
}

func BizWrap(err error, code string, message string, vars ...string) error {
	if err == nil {
		return nil
	}
	codeErr := &ErrWrap{
		cause: err,
		code:  code,
		vars:  vars,
	}
	err = &withMessage{
		cause: codeErr,
		msg:   message,
	}
	return &withStack{
		err,
		callers(),
	}
}

func DefaultBizWrap(code string, vars ...string) error {
	err := errors.New("")
	codeErr := &ErrWrap{
		cause: err,
		code:  code,
		vars:  vars,
	}
	err = &withMessage{
		cause: codeErr,
	}
	return &withStack{
		err,
		callers(),
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267

1.2 biz_err_demo/error/zerr/stack.go:堆栈打印格式

定义堆栈打印格式

package zerr

import (
	"fmt"
	"io"
	"path"
	"runtime"
	"strings"
)

type Frame uintptr

func (f Frame) pc() uintptr { return uintptr(f) - 1 }

func (f Frame) file() string {
	fn := runtime.FuncForPC(f.pc())
	if fn == nil {
		return "unknown"
	}
	file, _ := fn.FileLine(f.pc())
	return file
}

func (f Frame) line() int {
	fn := runtime.FuncForPC(f.pc())
	if fn == nil {
		return 0
	}
	_, line := fn.FileLine(f.pc())
	return line
}

func (f Frame) Format(s fmt.State, verb rune) {
	switch verb {
	case 's':
		switch {
		case s.Flag('+'):
			pc := f.pc()
			fn := runtime.FuncForPC(pc)
			if fn == nil {
				io.WriteString(s, "unknown")
			} else {
				file, _ := fn.FileLine(pc)
				fmt.Fprintf(s, "%s\n\t%s", fn.Name(), file)
			}
		default:
			io.WriteString(s, path.Base(f.file()))
		}
	case 'd':
		fmt.Fprintf(s, "%d", f.line())
	case 'n':
		name := runtime.FuncForPC(f.pc()).Name()
		io.WriteString(s, funcname(name))
	case 'v':
		f.Format(s, 's')
		io.WriteString(s, ":")
		f.Format(s, 'd')
	}
}

type StackTrace []Frame

func (st StackTrace) Format(s fmt.State, verb rune) {
	switch verb {
	case 'v':
		switch {
		case s.Flag('+'):
			for _, f := range st {
				fmt.Fprintf(s, "\n%+v", f)
			}
		case s.Flag('#'):
			fmt.Fprintf(s, "%#v", []Frame(st))
		default:
			fmt.Fprintf(s, "%v", []Frame(st))
		}
	case 's':
		fmt.Fprintf(s, "%s", []Frame(st))
	}
}

type stack []uintptr

func (s *stack) Format(st fmt.State, verb rune) {
	switch verb {
	case 'v':
		switch {
		case st.Flag('+'):
			for _, pc := range *s {
				f := Frame(pc)
				fmt.Fprintf(st, "\n%+v", f)
			}
		}
	}
}

func (s *stack) StackTrace() StackTrace {
	f := make([]Frame, len(*s))
	for i := 0; i < len(f); i++ {
		f[i] = Frame((*s)[i])
	}
	return f
}

func callers() *stack {
	const depth = 32
	var pcs [depth]uintptr
	n := runtime.Callers(3, pcs[:])
	if n > 1 {
		n = 1
	}
	var st stack = pcs[0:n]
	return &st
}

func funcname(name string) string {
	i := strings.LastIndex(name, "/")
	name = name[i+1:]
	i = strings.Index(name, ".")
	return name[i+1:]
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121

1.3 biz_err_demo/error/zerr/wrap.go:判断err类型

由自定义err,判断是否属于某个err

package zerr

import (
	"errors"
	"reflect"
)

func Unwrap(err error) error {
	u, ok := err.(interface {
		Cause() error
	})
	if !ok {
		return errors.Unwrap(err)
	}
	return u.Cause()
}

func Is(err, target error) bool {
	if target == nil {
		return err == target
	}

	isComparable := reflect.TypeOf(target).Comparable()
	for {
		if isComparable && err == target {
			return true
		}
		if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
			return true
		}
		if err = Unwrap(err); err == nil {
			return false
		}
	}
}

func As(err error, target interface{}) bool {
	if target == nil {
		panic("errors: target cannot be nil")
	}
	val := reflect.ValueOf(target)
	typ := val.Type()
	if typ.Kind() != reflect.Ptr || val.IsNil() {
		panic("errors: target must be a non-nil pointer")
	}
	targetType := typ.Elem()
	if targetType.Kind() != reflect.Interface && !targetType.Implements(errorType) {
		panic("errors: *target must be interface or implement error")
	}
	for err != nil {
		if reflect.TypeOf(err).AssignableTo(targetType) {
			val.Elem().Set(reflect.ValueOf(err))
			return true
		}
		if x, ok := err.(interface{ As(interface{}) bool }); ok && x.As(target) {
			return true
		}
		err = Unwrap(err)
	}
	return false
}

var errorType = reflect.TypeOf((*error)(nil)).Elem()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

1.4 biz_err_demo/error/biz_err/code.go:业务错误码

自定义业务错误码、对应错误信息及对应错误对应的httpStatusCode

package biz_err

import (
	"myTest/demo_home/biz_err_demo/error/zerr"
	"net/http"
	"strings"
)

const (
	Undefined                 = "Undefined"
	OsCreateFileError         = "OsCreateFileError"
	ImageNotSupported         = "ImageNotSupported"
	UsernameOrPasswordInValid = "UsernameOrPasswordInValid"
)

var errorResponseMap = map[string]string{
	OsCreateFileError:         "创建文件失败",
	ImageNotSupported:         "图片格式不支持",
	UsernameOrPasswordInValid: "用户名或密码错误",
}

var errorHttpStatusMap = map[string]int{
	OsCreateFileError:         http.StatusInternalServerError,
	ImageNotSupported:         http.StatusInternalServerError,
	UsernameOrPasswordInValid: http.StatusInternalServerError,
}

func ParseBizErr(err error) (httpStatus int, code, msg string) {
	if err == nil {
		code = Undefined
	}
	vars := make([]string, 0)
	errWrap := new(zerr.ErrWrap)
	var cause error
	if as := zerr.As(err, &errWrap); as {
		code = errWrap.Code()
		cause = errWrap.Cause()
		vars = errWrap.Vars()
	} else {
		code = Undefined
	}
	if code == Undefined {
		var undefinedMsg string
		if err != nil {
			undefinedMsg = err.Error()
		}
		if undefinedMsg == "" || undefinedMsg == ": " {
			undefinedMsg = errorResponseMap[code]
		}
		return errorHttpStatusMap[code], code, undefinedMsg
	}
	if status, ok := errorHttpStatusMap[code]; ok {
		httpStatus = status
	} else {
		httpStatus = http.StatusOK
	}
	if bizMsg, ok := errorResponseMap[code]; ok {
		for _, v := range vars {
			bizMsg = strings.Replace(bizMsg, "%s", v, 1)
		}
		msg = bizMsg
		if cause != nil {
			_, _, causeMsg := ParseBizErr(cause)
			if causeMsg != "" {
				msg += ", " + causeMsg
			} else {
				msg += ", " + errWrap.Error()
			}
		}
	} else {
		msg = errWrap.Error()
	}
	return httpStatus, code, msg
}

func ErrResponse(err error) (httpStatus int, code, msg string) {
	if err == nil {
		code = Undefined
	}
	vars := make([]string, 0)
	errWrap := new(zerr.ErrWrap)
	var cause error
	if as := zerr.As(err, &errWrap); as {
		code = errWrap.Code()
		cause = errWrap.Cause()
		vars = errWrap.Vars()
	} else {
		code = Undefined
	}
	if status, ok := errorHttpStatusMap[code]; ok {
		httpStatus = status
	} else {
		httpStatus = http.StatusOK
	}
	if bizMsg, ok := errorResponseMap[code]; ok {
		for _, v := range vars {
			bizMsg = strings.Replace(bizMsg, "%s", v, 1)
		}
		msg = bizMsg
		if cause != nil {
			_, _, causeMsg := ErrResponse(cause)
			if causeMsg != "" {
				msg += causeMsg
			} else {
				msg += errWrap.Error()
			}
		}
	} else {
		msg = errWrap.Error()
	}
	return httpStatus, code, msg
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112

2 controller:封装base_controller

2.1 biz_err_demo/constant/constant.go

package constant

const (
	ContentTypeJson = "application/json"
	ContentTypeXml  = "application/xml"
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2.2 biz_err_demo/controller/base_controller.go

package controller

import (
	"encoding/json"
	"encoding/xml"
	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/mvc"
	"github.com/sirupsen/logrus"
	"myTest/demo_home/biz_err_demo/constant"
	"myTest/demo_home/biz_err_demo/error/biz_err"
	"myTest/demo_home/biz_err_demo/response"
	"net/http"
)

type BaseController struct {
	Ctx iris.Context
}

func commonResp(errMsg string, httpCode int, returnCode response.Code, content interface{}) mvc.Response {
	payload := &response.JsonResponse{
		Code:    returnCode,
		Msg:     errMsg,
		Content: content,
	}

	contentDetail, err := json.Marshal(payload)
	if err != nil {
		logrus.Infof("marshal json response error %v", err)
	}

	return mvc.Response{
		Code:        httpCode,
		Content:     contentDetail,
		ContentType: constant.ContentTypeJson,
	}
}

func (c *BaseController) Xml(httpCode int, content interface{}) mvc.Response {
	payload, err := xml.Marshal(content)
	if err != nil {
		logrus.Errorf("marshal xml response error %v", err)
	}
	return c.XmlRaw(httpCode, payload)
}

func (c *BaseController) XmlOK(content interface{}) mvc.Response {
	payload, err := xml.Marshal(content)
	if err != nil {
		logrus.Errorf("marshal xml response error %v", err)
	}
	return c.XmlRaw(http.StatusOK, payload)
}

func (c *BaseController) XmlRaw(httpCode int, content []byte) mvc.Response {
	return mvc.Response{
		Code:        httpCode,
		Content:     content,
		ContentType: constant.ContentTypeXml,
	}
}

func (c *BaseController) JsonBizError(err error) mvc.Response {
	httpStatus, code, msg := biz_err.ErrResponse(err)
	return commonResp(msg, httpStatus, response.Code(code), nil)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

2.3 biz_err_demo/controller/test_biz_controller.go

package controller

import (
	"errors"
	"github.com/kataras/iris/v12/mvc"
	"myTest/demo_home/biz_err_demo/error/biz_err"
	"myTest/demo_home/biz_err_demo/error/zerr"
	"myTest/demo_home/biz_err_demo/response"
	"net/http"
)

type TestBizController struct {
	BaseController
}

func (t *TestBizController) BeforeActivation(b mvc.BeforeActivation) {
	b.Handle(http.MethodGet, "/testBizErr", "TestBizErr")
}

func (t *TestBizController) TestBizErr() mvc.Result {
	err1 := errors.New("")
	err := zerr.BizWrap(err1, biz_err.UsernameOrPasswordInValid, "")
	return response.JsonBizError(err)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

3 封装response

3.1 biz_err_demo/response/json_response.go

package response

import (
	"encoding/json"
	"github.com/kataras/iris/v12/mvc"
	"github.com/sirupsen/logrus"
	"myTest/demo_home/biz_err_demo/constant"
	"myTest/demo_home/biz_err_demo/error/biz_err"
)

type Code string

type JsonResponse struct {
	Code    Code        `json:"code"`
	Msg     string      `json:"msg"`
	Content interface{} `json:"content,omitempty"`
}

func JsonBizError(err error) mvc.Response {
	httpStatus, code, msg := biz_err.ErrResponse(err)
	return commonResp(msg, httpStatus, Code(code), nil)
}

func commonResp(errMsg string, httpCode int, returnCode Code, content interface{}) mvc.Response {
	payload := &JsonResponse{
		Code:    returnCode,
		Msg:     errMsg,
		Content: content,
	}

	contentDetail, err := json.Marshal(payload)
	if err != nil {
		logrus.Errorf("%v", err)
	}

	return mvc.Response{
		Code:        httpCode,
		Content:     contentDetail,
		ContentType: constant.ContentTypeJson,
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

4 测试效果

4.1 biz_err_demo/test/main.go

package main

import (
	"errors"
	"github.com/sirupsen/logrus"
	"myTest/demo_home/biz_err_demo/error/biz_err"
	"myTest/demo_home/biz_err_demo/error/zerr"
)

func init() {
	logrus.SetReportCaller(true) // 设置日志是否记录被调用的位置,默认值为 false
}

func main() {
	TestWithNoSourceErr()
	TestWithSourceErr()
	TestParseBizErr()
}

func TestWithNoSourceErr() {
	err := zerr.DefaultBizWrap(biz_err.UsernameOrPasswordInValid, "")
	logrus.Errorf("TestWithNoSourceErr %+v", err)
}

func TestWithSourceErr() {
	err := errors.New("invalid image")
	err = zerr.BizWrap(err, biz_err.ImageNotSupported, "")
	logrus.Errorf("TestWithSourceErr %+v", err)
}

func TestParseBizErr() {
	err := errors.New("")
	err = zerr.BizWrap(err, biz_err.ImageNotSupported, "")
	httpStatus, bizCode, msg := biz_err.ParseBizErr(err)
	logrus.Errorf("httpStatus:%d bizCode:%s msg:%s", httpStatus, bizCode, msg)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

在这里插入图片描述

4.2 biz_err_demo/main.go

package main

import (
	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/mvc"
	"myTest/demo_home/biz_err_demo/controller"
)

func main() {
	app := iris.New()
	mvc.New(app).Handle(new(controller.TestBizController))
	app.Listen(":8088", nil)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在这里插入图片描述

这样前端就能直接根据我们的业务错误码展示对应msg信息

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/42768
推荐阅读
  

闽ICP备14008679号