go-zero(四) 错误处理(统一响应信息)
go-zero 错误处理(统一响应信息)
在实现注册逻辑时,尝试重复注册可能会返回 400 状态码,显然不符合正常设计思维。我们希望状态码为 200,并在响应中返回错误信息。
一、使用第三方库
1.下载库
目前 go-zero官方的 zeromicro 下有一个 x 仓库,可以实现统一响应格式,我们先安装下:
go get github.com/zeromicro/x
它会自动帮我们把响应信息改为下面这种格式:
{
"code": 0,
"msg": "ok",
"data": {
...
}
}
2.修改handler
接着我们修改internal/handler/register/registerhandler.go
文件,把原来的响应处理,替换成这个库的:
//导入zeromicro库并设置别名,避免和原生的http冲突
import (
xhttp "github.com/zeromicro/x/http"
)
//修改RegisterHandler的返回信息
func RegisterHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.RegisterRequest
if err := httpx.Parse(r, &req); err != nil {
//使用xhttp.JsonBaseResponseCtx 替换掉httpx.ErrorCtx
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
//httpx.ErrorCtx(r.Context(), w, err)
return
}
l := register.NewRegisterLogic(r.Context(), svcCtx)
resp, err := l.Register(&req)
if err != nil {
//使用xhttp.JsonBaseResponseCtx 替换掉httpx.ErrorCtx
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
//httpx.ErrorCtx(r.Context(), w, err)
} else {
//使用xhttp.JsonBaseResponseCtx 替换掉httpx.OkJsonCtx
xhttp.JsonBaseResponseCtx(r.Context(), w, resp)
//httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
3.修改返回错误
在internal/logic/user/registerlogic.go
文件中,把原来的err
修改成 errors.New()
,它的参数有两个,一个是用来返回 code码 ,还有一个是message消息:
func (l *RegisterLogic) Register(req *types.RegisterRequest) (resp *types.RegisterResponse, err error) {
// todo: add your logic here and delete this line
/*
.....
*/
if user != nil {
//return nil, err
return nil, errors.New(1, "用户已注册")
}
//插入新的数据
/*
.....
*/
if err != nil {
//return nil, err
return nil, errors.New(2, "用户注册失败")
}
}
接着我们运行项目,使用Postman重新测试,结果如下:
二、自定义错误管理
如果你不想使用这个库,或者想自己实现一些自定义错误,那么你也可以自己设置错误管理
1.自定义错误结构与格式化
我们在internal
目录下新建biz
目录,用于业务处理,然后再这个目录下分别创建3个文件
创建biz.go
文件
package biz
type Error struct {
Code int `json:"code"`
Msg string `json:"msg"`
}
func NewError(code int, msg string) *Error {
return &Error{
Code: code,
Msg: msg,
}
}
func (e *Error) Error() string {
return e.Msg
}
创建resp.go
文件
package biz
type Result struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data any `json:"data"`
}
func Success(data any) *Result {
return &Result{
Code: Ok,
Msg: "success",
Data: data,
}
}
func Fail(err *Error) *Result {
return &Result{
Code: err.Code,
Msg: err.Msg,
}
}
创建vars.go
文件
package biz
const Ok = 200
var (
AlreadyRegister = NewError(1, "用户已注册")
PasswordErr = NewError(2, "密码错误")
InsertErr = NewError(3, "用户注册失败")
)
2. 使用 httpx.Error 和 httpx.SetErrorHandler
接着修改user.go
文件:
/*
....
*/
defer server.Stop()
//httpx.SetErrorHandler 函数可以帮助你定义一个全局的错误处理逻辑,
//该逻辑会在 HTTP handler 中捕获到的所有错误中执行。
//它将允许你统一处理各类错误,返回更加一致和用户友好的响应。
//httpx.SetErrorHandler 仅在调用了 httpx.Error 处理响应时才有效。
httpx.SetErrorHandler(func(err error) (int, any) {
switch e := err.(type) {
case *biz.Error:
// 自定义一个 错误返回类型
return http.StatusOK, biz.Fail(e)
default:
return http.StatusInternalServerError, nil
}
})
ctx := svc.NewServiceContext(c)
/*
....
*/
修改internal/handler/register/registerhandler.go
文件:
func RegisterHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.RegisterRequest
if err := httpx.Parse(r, &req); err != nil {
//httpx.SetErrorHandler 仅在调用了 httpx.Error 处理响应时才有效。
//所以我们现在还是使用原来的httpx.ErrorCtx
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := register.NewRegisterLogic(r.Context(), svcCtx)
resp, err := l.Register(&req)
if err != nil {
//httpx.SetErrorHandler 仅在调用了 httpx.Error 处理响应时才有效。
//所以我们现在还是使用原来的httpx.ErrorCtx
httpx.ErrorCtx(r.Context(), w, err)
} else {
//成功的请求,httpx.SetErrorHandler 是捕获不到的
// 所以需要我们自定义返回信息
httpx.OkJsonCtx(r.Context(), w, biz.Success(resp))
}
}
}
3.实现统一的错误响应机制
接下来,修改 internal/user/register/registerlogic.go
文件:
func (l *RegisterLogic) Register(req *types.RegisterRequest) (resp *types.RegisterResponse, err error) {
// todo: add your logic here and delete this line
/*
...
*/
if user != nil {
//return nil, errors.New(1, "用户已注册")
return nil, biz.AlreadyRegister
}
//插入新的数据
/*
...
*/
if err != nil {
//return nil, errors.New(2, "用户注册失败")
return nil, biz.InsertErr
}
}
接着运行测试
原文地址:https://blog.csdn.net/yang731227/article/details/143837350
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!