```
feat(business_error): 添加业务异常处理示例和mcube异常库集成 - 创建完整的业务异常处理文档,包含error接口说明、封装方法 - 实现自定义ApiException结构体,支持HTTP状态码、业务异常码等字段 - 集成mcube/v2异常库作为第三方依赖,版本v2.0.91 - 提供ValidateToken函数
This commit is contained in:
parent
aa35d086f8
commit
4b2709ecd9
@ -1,2 +1,124 @@
|
|||||||
# 业务异常
|
# 业务异常
|
||||||
|
|
||||||
|
[课件](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
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|||||||
5
day05/business_error/go.mod
Normal file
5
day05/business_error/go.mod
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module business_error
|
||||||
|
|
||||||
|
go 1.25.6
|
||||||
|
|
||||||
|
require github.com/infraboard/mcube/v2 v2.0.91
|
||||||
2
day05/business_error/go.sum
Normal file
2
day05/business_error/go.sum
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
github.com/infraboard/mcube/v2 v2.0.91 h1:2araVdjB3MXU6OJqZMdh2KQSJXYu12kIk7pRsAXEd78=
|
||||||
|
github.com/infraboard/mcube/v2 v2.0.91/go.mod h1:hjVvjY7dpW4jMRBV8rUYikobqP2c0vR7Q5knmRTERsQ=
|
||||||
64
day05/business_error/main.go
Normal file
64
day05/business_error/main.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 辅助函数: IsApiException 判断是否是ApiException
|
||||||
|
// func IsApiException(err error, code int) bool {
|
||||||
|
// if v, ok := err.(*ApiException); ok {
|
||||||
|
// return v.Code == code
|
||||||
|
// }
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
Loading…
x
Reference in New Issue
Block a user