1、原生错误处理
Go 语言通过内置的错误接口提供了非常简单的错误处理机制。 error类型是一个接口类型,这是它的定义:
type error interface {
Error() string
}
我们可以在编码中通过实现 error 接口类型来生成错误信息。 函数通常在最后的返回值中返回错误信息。使用errors.New 可返回一个错误信息:
func Sqrt(f float64) (float64, error) {
if f < 0 {
return 0, errors.New("math: square root of negative number")
}
// 实现
}
在下面的例子中,我们在调用Sqrt的时候传递的一个负数,然后就得到了non-nil的error对象,将此对象与nil比较,结果为true,所以fmt.Println(fmt包在处理error时会调用Error方法)被调用,以输出错误,请看下面调用的示例代码:
result, err:= Sqrt(-1)
if err != nil {
fmt.Println(err)
}
2、开源error包
github.com/pkg/errors包在原生error包基础上增加了以下常用的功能:
-
可以打印error的堆栈信息:打印错误需要%+v才能详细输出
-
使用Wrap或Wrapf,初始化一个error
-
使用errors.WithMessage可以在原来的error基础上再包装一层,包含原有error信息
-
errors.Is,用于判断error类型,可根据error类型不同做不同处理
-
errors.As,用于解析error
具体使用案例见全局错误处理一节。
3、工程中错误处理
3.1 需求整理
-
自定义error信息,并进行编码整理
-
controller层可以判断自定义error类型,最终判断是按info处理,还是按error处理
-
-
可以打印error初始发生的位置(获取error的调用栈)
-
确认当前系统定位:
-
用户,获取TagMessage
-
上游服务,需要错误码映射
-
日志监控、监控TagMessage
-
下面在一个工程化的项目中利用github.com/pkg/errors
包,完整实现一套的错误处理机制
3.2 方式一:Map保存错误码与Message的映射
3.2.1 定义错误信息
新建error_handler.go
package error_handle
import (
"github.com/pkg/errors"
)
// 1、自定义error结构体,并重写Error()方法
// 错误时返回自定义结构
type CustomError struct {
Code int `json:"code"` // 业务码
TagMessage string `json:"message"` // 描述信息
}
func (e *CustomError) Error() string {
return e.TagMessage
}
// 2、定义errorCode
const (
// 服务级错误码
ServerError = 10101
TooManyRequests = 10102
ParamBindError = 10103
AuthorizationError = 10104
CallHTTPError = 10105
ResubmitError = 10106
ResubmitMsg = 10107
HashIdsDecodeError = 10108
SignatureError = 10109
// 业务模块级错误码
// 用户模块
IllegalUserName = 20101
UserCreateError = 20102
UserUpdateError = 20103
UserSearchError = 20104
// 授权调用方
AuthorizedCreateError = 20201
AuthorizedListError = 20202
AuthorizedDeleteError = 20203
AuthorizedUpdateError = 20204
AuthorizedDetailError = 20205
AuthorizedCreateAPIError = 20206
AuthorizedListAPIError = 20207
AuthorizedDe