基于 Golang int 枚举的错误类型生成工具
代码链接:https://github.com/fengxuway/errcode
errcode 是一个附带错误码的 error 生成工具
源代码基于 https://github.com/golang/tools/tree/master/cmd/stringer ,并在此基础上,增加了根据 error 获取错误码的功能。
安装
go install github.com/fengxuway/errcode@latest
用法
编写自定义类型的 int 枚举,并为每个常量添加注释
type Err int
const (
ErrNotFound Err = iota + 1 // not found
ErrBadRequest // bad request
ErrUnknown // unknown error
)
使用 errcode 命令为 Err类型生成 Error() 等 error 接口方法:
errcode -type=Err --linecomment -codefunc=Code -unknowncode=-1
可在同级目录下生成 *_errcode.go源代码文件,内部定义了 String(),Error() 方法,和 Code(error) int 函数,用于获取 error 对应的错误码
部分参数含义:
-type: 指定需要生成错误码的枚举类型,同时指定多个用,分隔
--linecomment: 读取常量行级注释,作为 error message 信息
-codefunc: 指定获取错误码的函数名称,默认为 Code
-unknowncode: 当 Code 函数传入的 error 没有匹配时返回的未知错误码,默认-1
完整示例见 https://github.com/fengxuway/errcode/tree/main/example
效果
生成的代码效果大致为:
// Code generated by "errcode -type=Err,Err2 --linecomment -unknowncode=-1 -codefunc=Code"; DO NOT EDIT.
package example
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the errcode command to generate them again.
var x [1]struct{}
_ = x[ErrPlanIsEmpty-10]
_ = x[ErrManualCreateFailed-11]
_ = x[ErrRPCFailed-12]
_ = x[ErrStageNotMatched-13]
_ = x[ErrNoAvailable-14]
_ = x[ErrUnmarshalFailed-15]
_ = x[ErrGetFailed-17]
_ = x[ErrPlanNotSupport-18]
_ = x[ErrDBFailed-19]
}
const (
_Err_name_0 = "plan is emptymanual create operation failedrpc request failedstage not matchednot availablejson unmarshal failed"
_Err_name_1 = "get data failedplan not supportdb operation failed"
)
var (
_Err_index_0 = [...]uint8{0, 13, 43, 61, 78, 91, 112}
_Err_index_1 = [...]uint8{0, 15, 31, 50}
)
func (i Err) Error() string {
return i.String()
}
func (i Err) String() string {
switch {
case 10 <= i && i <= 15:
i -= 10
return _Err_name_0[_Err_index_0[i]:_Err_index_0[i+1]]
case 17 <= i && i <= 19:
i -= 17
return _Err_name_1[_Err_index_1[i]:_Err_index_1[i+1]]
default:
return "Err(" + strconv.FormatInt(int64(i), 10) + ")"
}
}
var _ecCodeMap = map[string]int{
ErrPlanIsEmpty.String(): int(ErrPlanIsEmpty),
ErrManualCreateFailed.String(): int(ErrManualCreateFailed),
ErrRPCFailed.String(): int(ErrRPCFailed),
ErrStageNotMatched.String(): int(ErrStageNotMatched),
ErrNoAvailable.String(): int(ErrNoAvailable),
ErrUnmarshalFailed.String(): int(ErrUnmarshalFailed),
ErrGetFailed.String(): int(ErrGetFailed),
ErrPlanNotSupport.String(): int(ErrPlanNotSupport),
ErrDBFailed.String(): int(ErrDBFailed),
}
func Code(e error) int {
v, ok := _ecCodeMap[e.Error()]
if ok {
return v
}
return -1
}
调用效果
var err error = ErrNotFound
# 打印错误信息
fmt.Println(err.Error())
// 打印错误码
fmt.Println(Code(err))