# 业务异常 [课件](https://gitee.com/infraboard/go-course/blob/master/zh-cn/base/exception.md) ## error 是接口 ```go type error interface { Error() string } ``` ## 封装 error ```go // fmt.Errorf("token is empty") type wrapError struct { msg string err error } func (e *wrapError) Error() string { return e.msg } func (e *wrapError) Unwrap() error { return e.err } ``` ## 自定义业务异常 ```go func NewApiException(code int, message string) *ApiException { return &ApiException{ HttpCode: 500, Code: code, Message: message, Meta: map[string]any{}, Data: map[string]any{}, } } // ApiException API异常结构体 // 自定义异常数据结构体, 方便后续的异常处理和日志记录 type ApiException struct { Service string `json:"service"` // 服务名称, 你后端服务多个 HttpCode int `json:"http_code,omitempty"` // HTTP状态码, 需不需定义明确的http code, 默认500,非2xx Code int `json:"code"` // 业务异常码, 具体业务自己定义 Reason string `json:"reason"` // 异常原因 Message string `json:"message"` // 详细描述 Meta map[string]any `json:"meta"` // 元数据 Data any `json:"data"` // 附加数据 } func (e *ApiException) Error() string { return e.Message } // ToJson 转为JSON字符串,方便接口返回 func (e *ApiException) ToJson() string { dj, _ := json.Marshal(e) return string(dj) } // 辅助函数: IsApiException 判断是否是ApiException func IsApiException(err error, code int) bool { if v, ok := err.(*ApiException); ok { return v.Code == code } return false } ``` ## mcube ApiException库 1. 如何为你的项目引入3方包:(体验) ```sh # 1. 找到你需要安装的3方包: "github.com/infraboard/mcube/v2/exception" # 2. 为你的工程安装该包: go get "github.com/infraboard/mcube/v2/exception"(项目目录) # 3. 初始化一个go工程(go.mod的工程文件): go mod init <工程名称: business_error> # 4. 当前 go.mod所在目录的工程,就是一个 Go标准工程 # 5. 可以使用 go get来安装3方依赖 ➜ business_error git:(main) ✗ go get "github.com/infraboard/mcube/v2/exception" go: downloading github.com/infraboard/mcube/v2 v2.0.91 go: added github.com/infraboard/mcube/v2 v2.0.91 # "github.com/infraboard/mcube/v2/exception",使用这个包: exception.NewApiException(10001, "token is empty") # exception 是包的名称: 大多数情况就是 路径里面最后一个目录(package 定义的名称), . 引入包里面的各种资源(大写开头): 函数,变量,类型(Struct,自定义类型, ...) # 包就是把 公共的工具或者能力 维护到一个地方(包),方便多个项目 引入使用 ``` ```go package main import ( "encoding/json" "fmt" // "github.com/infraboard/mcube/v2/exception" ) func main() { err := ValidateToken("") if err != nil { fmt.Println(err) bj, _ := json.Marshal(err) fmt.Println(string(bj)) // {"service":"","http_code":500,"code":10001,"reason":"","message":"token is empty","meta":{},"data":{}} if exception.IsApiException(err, 10001) { fmt.Println("IsApiException: token is empty") } } } func ValidateToken(token string) error { if token == "" { return exception.NewApiException(10001, "token is empty") } return nil } ```