go-zero统一Response的返回值(RPC端错误没有解析到)

统一Response的返回值

说明

最完整版本推荐使用当前项目方式,支持捕捉RPC端,官方后续好像会支持这种错误模式(作者提过)
github.com/Mikaelemmmm/go-zero-loo...

官方参考资料

参考1:官网的【模板管理】=》【自定义模板】

go-zero.dev/cn/template.html

参考2:官网的【项目开发】=》【业务开发】=》【错误处理】

go-zero.dev/cn/error-handle.html

步骤一:新创建自己的错误处理相关函数

【说明】:你拿去使用,需要将”go-slot/utils/errorx”等import路径改成你自己实际的路径。我当前项目名称叫go-slot,utils是我的一个工具包。

1.官方给的代码:


package response

import (

 "net/http"

 "github.com/tal-tech/go-zero/rest/httpx"

)

type  Body  struct {

Code int  `json:"code"`

    Msg  string `json:"msg"`

Data interface{} `json:"data,omitempty"`

}

func  Response(w http.ResponseWriter, resp interface{}, err error) {

 var  body Body

 if err != nil {

 body.Code = -1

 body.Msg = err.Error()

} else {

 body.Msg = "OK"

 body.Data = resp

    }

    httpx.OkJson(w, body)

}
  1. 我此时修改的代码目录如下,代码拿去,需要你自己修改相关的import信息,小呆瓜别直接用

//baseerror.go和response.go的路径

utils

├─ common.go

├─ errorx

│  └─ baseerror.go

├─ http_rpc.go

├─ md5.go

└─ response

   └─ response.go

2.1. utils/response/response.go代码如下:


//utils/response/response.go代码

package response

import (

 "github.com/tal-tech/go-zero/rest/httpx"

 "go-slot/utils/errorx"

 "net/http"

)

type  Body  struct {

Code int  `json:"code"`

    Message  string `json:"msg"`

Data interface{} `json:"data,omitempty"`

}

//统一封装成功响应值

func  Response(w http.ResponseWriter, resp interface{}, err error) {

 var  body Body

 if err != nil {

 switch  e := err.(type) {

 case *errorx.CodeError://业务输出错误

 body.Code = e.Code

 body.Message = e.Message

 body.Data = e.Data

 //body.Data = e.Data()

 default: //系统未知错误

 body.Code = 1

 body.Message = err.Error()

        }

} else {

 body.Code = 0

 body.Message = "请求成功!"

 body.Data = resp

    }

    httpx.OkJson(w, body)

}

2.2. utils/errorx/baseerror.go代码如下:


package errorx

//定义错误类型

const  defaultCode = 1001

type  CodeError  struct {

    Code    int `json:"code"`

Message string  `json:"message"`

Data interface{} `json:"data,omitempty"`

}

func  NewCodeError(code int, msg string) error {

 return &CodeError{Code: code, Message: msg}

}

func  NewErrorData(code int, msg string,data interface{}) error {

 return &CodeError{Code: code, Message: msg, Data: data}

}

func  NewDefaultError(msg string) error {

 return  NewCodeError(defaultCode, msg)

}

func (e *CodeError) Error() string {

 return e.Message

}

//------------------Response响应值----------------------

//func (e *CodeError) Info()响应返回值

type  CodeErrorResponse  struct {

    Code    int `json:"code"`

Message string  `json:"message"`

Data interface{} `json:"data,omitempty"`

}

//返回相关参数

func (e *CodeError) Info() *CodeErrorResponse {

 return &CodeErrorResponse{

        Code:    e.Code,

        Message: e.Message,

        Data:   e.Data,

    }

}

步骤二:生成本地goctl缓存模板

1.随机开启一个CMD窗口使用模板初始化命令goctl template init进行初始化,如果本地没有~/.goctl/api/handler.tpl文件 的话。

mac环境对应的路径就是~/.goctl/api。

window路径会是C:\Users\【你的电脑用户名】.goctl,此时我的模板路径是C:\Users\DELL.goctl\1.2.3-cli\api,其中DELL是此时的用户名。

goctl完整模板结构如下:


.goctl

└─ 1.2.3-cli

   ├─ api

   │  ├─ config.tpl

   │  ├─ context.tpl

   │  ├─ etc.tpl

   │  ├─ handler.tpl

   │  ├─ handler官方模板.tpl

   │  ├─ logic.tpl

   │  ├─ main.tpl

   │  └─ template.tpl

   ├─ docker

   │  └─ docker.tpl

   ├─ kube

   │  ├─ deployment.tpl

   │  └─ job.tpl

   ├─ model

   │  ├─ delete.tpl

   │  ├─ err.tpl

   │  ├─ field.tpl

   │  ├─ find-one-by-field-extra-method.tpl

   │  ├─ find-one-by-field.tpl

   │  ├─ find-one.tpl

   │  ├─ import-no-cache.tpl

   │  ├─ import.tpl

   │  ├─ insert.tpl

│  ├─ interface-delete.tpl

│  ├─ interface-find-one-by-field.tpl

│  ├─ interface-find-one.tpl

│  ├─ interface-insert.tpl

│  ├─ interface-update.tpl

   │  ├─ model-new.tpl

   │  ├─ model.tpl

   │  ├─ tag.tpl

   │  ├─ types.tpl

   │  ├─ update.tpl

   │  └─ var.tpl

   ├─ mongo

   │  ├─ err.tpl

   │  └─ model.tpl

   ├─ newapi

   │  └─ newtemplate.tpl

   └─ rpc

      ├─ call-func.tpl

      ├─ call-interface-func.tpl

      ├─ call.tpl

      ├─ config.tpl

      ├─ etc.tpl

      ├─ logic-func.tpl

      ├─ logic.tpl

      ├─ main.tpl

      ├─ server-func.tpl

      ├─ server.tpl

      ├─ svc.tpl

      └─ template.tpl

步骤三:修改goctl的handel模板

【说明】:你拿去使用需要修改import

3.1. 官方默认的handel模板


package {{.PkgName}}

import (

 "net/http"

    {{if .After1_1_10}}"github.com/tal-tech/go-zero/rest/httpx"{{end}}

    {{.ImportPackages}}

)

func {{.HandlerName}}(ctx *svc.ServiceContext) http.HandlerFunc {

 return  func(w http.ResponseWriter, r *http.Request) {

        {{if .HasRequest}}var  req types.{{.RequestType}}

 if  err := httpx.Parse(r, &req); err != nil {

            httpx.Error(w, err)

 return

        }

        {{end}}l := {{.LogicName}}.New{{.LogicType}}(r.Context(), ctx)

        {{if .HasResp}}resp, {{end}}err := l.{{.Call}}({{if .HasRequest}}req{{end}})

 if err != nil {

            httpx.Error(w, err)

} else {

            {{if .HasResp}}httpx.OkJson(w, resp){{else}}httpx.Ok(w){{end}}

        }

    }

}

3.2. 我修改之后的handel模板完整代码


package {{.PkgName}}

import (

 "go-slot/utils/response"

 "net/http"

    {{if .After1_1_10}}"github.com/tal-tech/go-zero/rest/httpx"{{end}}

    {{.ImportPackages}}

)

func {{.HandlerName}}(ctx *svc.ServiceContext) http.HandlerFunc {

 return  func(w http.ResponseWriter, r *http.Request) {

        {{if .HasRequest}}var  req types.{{.RequestType}}

 if  err := httpx.Parse(r, &req); err != nil {

            httpx.Error(w, err)

 return

        }

        {{end}}l := {{.LogicName}}.New{{.LogicType}}(r.Context(), ctx)

        {{if .HasResp}}resp, {{end}}err := l.{{.Call}}({{if .HasRequest}}req{{end}})

        {{if .HasResp}}response.Response(w, resp, err){{else}}response.Response(w, nil, err){{end}}

    }

}

其实就是做了2件事情。

第1件事:删除官方模板的如下代码


 if err != nil {

            httpx.Error(w, err)

} else {

            {{if .HasResp}}httpx.OkJson(w, resp){{else}}httpx.Ok(w){{end}}

        }

第2件事:新增如下代码,其中


{{if .HasResp}}response.Response(w, resp, err){{else}}response.Response(w, nil, err){{end}}

//注意导入你自己response.Response对应的import

步骤四:去任意一个logic的方法验证结果


//记得import自己对应的路径

err := errorx.NewDefaultError("添加会员地址失败") //默认code错误

err := errorx.NewErrorData(400,"错误","数据错误") //指定任意错误data信息

err := errorx.NewCodeError(400,"错误") //指定code和message信息
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!