设为首页 加入收藏

TOP

go-zero docker-compose 搭建课件服务(九):http统一返回和集成日志服务(一)
2023-07-23 13:28:57 】 浏览:101
Tags:go-zero docker-compose http 成日志

0、索引

go-zero docker-compose 搭建课件服务(九):http统一返回和集成日志服务

0.1源码地址

https://github.com/liuyuede123/go-zero-courseware

1、http统一返回

一般返回中会有codemessagedata。当请求成功的时候code返回0或者200,message返回success,data为要获取的数据;当请求失败的时候code返回自定义的错误码,message返回展示给前端的错误信息,data为空。

我们将封装一个错误返回的函数,应用到api handler的返回

在user服务中创建了common文件夹,里面存一些公用的方法,创建response/response.go

package response

import (
	"go-zero-courseware/user/common/xerr"
	"net/http"

	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/rest/httpx"
	"google.golang.org/grpc/status"
)

type Response struct {
	Code    uint32      `json:"code"`
	Message string      `json:"message"`
	Data    interface{} `json:"data"`
}

//http返回
func HttpResult(r *http.Request, w http.ResponseWriter, resp interface{}, err error) {

	if err == nil {
		//成功返回
		r := &Response{
			Code:    0,
			Message: "success",
			Data:    resp,
		}
		httpx.WriteJson(w, http.StatusOK, r)
	} else {
		//错误返回
		errcode := uint32(500)
		errmsg := "服务器错误"

		causeErr := errors.Cause(err)                // err类型
		if e, ok := causeErr.(*xerr.CodeError); ok { //自定义错误类型
			//自定义CodeError
			errcode = e.GetErrCode()
			errmsg = e.GetErrMsg()
		} else {
			if gstatus, ok := status.FromError(causeErr); ok { // grpc err错误
				grpcCode := uint32(gstatus.Code())
				errcode = grpcCode
				errmsg = gstatus.Message()
			}
		}

		logx.WithContext(r.Context()).Errorf("【API-ERR】 : %+v ", err)

		httpx.WriteJson(w, http.StatusBadRequest, &Response{
			Code:    errcode,
			Message: errmsg,
			Data:    nil,
		})
	}
}

创建xerr/errors.go文件,定义CodeError结构体

package xerr

import (
	"fmt"
)

/**
常用通用固定错误
*/
type CodeError struct {
	errCode uint32
	errMsg  string
}

//返回给前端的错误码
func (e *CodeError) GetErrCode() uint32 {
	return e.errCode
}

//返回给前端显示端错误信息
func (e *CodeError) GetErrMsg() string {
	return e.errMsg
}

func (e *CodeError) Error() string {
	return fmt.Sprintf("ErrCode:%d,ErrMsg:%s", e.errCode, e.errMsg)
}

func NewErrCodeMsg(errCode uint32, errMsg string) *CodeError {
	return &CodeError{errCode: errCode, errMsg: errMsg}
}

由于api一般调用的rpc的请求,获取到的错误无法展示给前端使用,我们会使用自定义的错误类型。当让rpc中的错误也可能是前端直接可以展示的错误,或者是数据库的某个异常抛出的错误,如果想区分这些错误,可以自己定义业务端code和message做下区分就行。这里我们统一api服务中处理。

当api或者rpc中有一些未知错误抛出的时候我们需要写入到日志中,包括具体的错误信息和堆栈信息。这些后续放到日志服务ELK中可以方便查看。

修改userinfohandler.go、userloginhandler.go、userregisterhandler.go中的返回

...

response.HttpResult(r, w, resp, err)

修改userinfologic.go

...

func (l *UserInfoLogic) UserInfo(req *types.UserInfoRequest) (resp *types.UserInfoResponse, err error) {
	info, err := l.svcCtx.UserRpc.UserInfo(l.ctx, &userclient.UserInfoRequest{
		Id: req.Id,
	})
	if err != nil {
    // 自定义的错误返回
		return nil, xerr.NewErrCodeMsg(500, "用户查询失败")
	}

	return &types.UserInfoResponse{
		Id:        info.Id,
		Username:  info.Username,
		LoginName: info.LoginName,
		Sex:       info.Sex,
	}, nil
}

修改userloginlogic.go

...

func (l *UserLoginLogic) UserLogin(req *types.LoginRequest) (resp *types.LoginResponse, err error) {
	login, err := l.svcCtx.UserRpc.Login(l.ctx, &userclient.LoginRequest{
	
首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇goroutine&waitgroup下载文件 下一篇Golang GMP原理(1)

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目