关于 Kitex 项目中的错误处理(框架)
Kitex 中 error 处理
先在 pkg/errno 目录下定义出项目所需要的错误类型(错误码 + 错误信息)实现一些必要的 api (创建、输出、错误信息添加)
继续在 pkg/errno 目录下定义出将 error 转化为 BaseResp (基本响应类型) 的代码 过程为 error -> errno (自定义的) ->baseResp
Go 中的 error
在 Go 语言中,error 是一个内置的接口类型,用于表示错误。它的定义如下:
1 2 3
| type error interface { Error() string }
|
所以只需要实现了 Error 方法,该结构体就可以作为 error 接口类型的一个实现
errno
错误 (码) 类型自定义
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
| package errno
import ( "errors" "fmt" )
const ( SuccessCode = 0 ServiceErrCode = 10001 ParamErrCode = 10002
LoginErrCode = 11001 UserNotExistErrCode = 11002 UserAlreadyExistErrCode = 11003 )
type ErrNo struct { ErrCode int64 ErrMsg string }
func (e ErrNo) Error() string { return fmt.Sprintf("err_code=%d, err_msg=%s", e.ErrCode, e.ErrMsg) }
func NewErrNo(code int64, msg string) ErrNo { return ErrNo{code, msg} }
func (e ErrNo) WithMessage(msg string) ErrNo { e.ErrMsg = msg return e }
var ( Success = NewErrNo(SuccessCode, "Success") ServiceErr = NewErrNo(ServiceErrCode, "Service is unable to start successfully") ParamErr = NewErrNo(ParamErrCode, "Wrong Parameter has been given") LoginErr = NewErrNo(LoginErrCode, "Wrong username or password") UserNotExistErr = NewErrNo(UserNotExistErrCode, "User does not exists") UserAlreadyExistErr = NewErrNo(UserAlreadyExistErrCode, "User already exists") )
func ConvertErr(err error) ErrNo { Err := ErrNo{} if errors.As(err, &Err) { return Err }
s := ServiceErr s.ErrMsg = err.Error() return s }
|
从 error
构建 baseResp
注意 BuildBaseResp(err error)
使用 error 这种接口类型作为参数
我们实现的 ErrN0 结构体作为 error (接口) 类型的一个实现,同样也可以作为参数进行传递
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
| package errno
import ( "errors" "git.nju.edu.cn/13_2024_fall_devops/13_2024_fall_devops_server/kitex_gen/base" )
func BuildBaseResp(err error) *base.BaseResp { if err == nil { return baseResp(Success) }
e := ErrNo{} if errors.As(err, &e) { return baseResp(e) }
s := ServiceErr.WithMessage(err.Error()) return baseResp(s) }
func baseResp(err ErrNo) *base.BaseResp { return &base.BaseResp{StatusCode: int32(err.ErrCode), StatusMessage: err.ErrMsg} }
|
使用定义好的错误类型抛出错误
1 2 3 4 5 6 7 8 9 10 11 12 13
| func (s *UserServiceImpl) CreateUser(ctx context.Context, req *user.CreateUserReq) (resp *user.CreateUserResp, err error) { resp = user.NewCreateUserResp()
err = service.NewUserService(ctx).CreateUser(req) if err != nil { resp.BaseResp = errno.BuildBaseResp(err) return resp, nil } resp.BaseResp = errno.BuildBaseResp(errno.Success) return resp, nil }
|