go-zero 錯(cuò)誤處理

2022-04-21 11:04 更新

錯(cuò)誤處理

錯(cuò)誤的處理是一個(gè)服務(wù)必不可缺的環(huán)節(jié)。在平時(shí)的業(yè)務(wù)開(kāi)發(fā)中,我們可以認(rèn)為http狀態(tài)碼不為2xx系列的,都可以認(rèn)為是http請(qǐng)求錯(cuò)誤, 并伴隨響應(yīng)的錯(cuò)誤信息,但這些錯(cuò)誤信息都是以plain text形式返回的。除此之外,我在業(yè)務(wù)中還會(huì)定義一些業(yè)務(wù)性錯(cuò)誤,常用做法都是通過(guò) code、msg 兩個(gè)字段來(lái)進(jìn)行業(yè)務(wù)處理結(jié)果描述,并且希望能夠以json響應(yīng)體來(lái)進(jìn)行響應(yīng)。

業(yè)務(wù)錯(cuò)誤響應(yīng)格式

  • 業(yè)務(wù)處理正常

  {
    "code": 0,
    "msg": "successful",
    "data": {
      ....
    }
  }

  • 業(yè)務(wù)處理異常

  {
    "code": 10001,
    "msg": "參數(shù)錯(cuò)誤"
  }

user api之login

在之前,我們?cè)诘卿涍壿嬛刑幚碛脩?hù)名不存在時(shí),直接返回來(lái)一個(gè)error。我們來(lái)登錄并傳遞一個(gè)不存在的用戶(hù)名看看效果。

curl -X POST \
  http://127.0.0.1:8888/user/login \
  -H 'content-type: application/json' \
  -d '{
    "username":"1",
    "password":"123456"
}'
HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
Date: Tue, 09 Feb 2021 06:38:42 GMT
Content-Length: 19

用戶(hù)名不存在

接下來(lái)我們將其以json格式進(jìn)行返回

自定義錯(cuò)誤

  • 首先在common中添加一個(gè)baseerror.go文件,并填入代碼

  $ cd common
  $ mkdir errorx&&cd errorx
  $ vim baseerror.go
  package errorx

  const defaultCode = 1001

  type CodeError struct {
      Code int    `json:"code"`
      Msg  string `json:"msg"`
  }

  type CodeErrorResponse struct {
      Code int    `json:"code"`
      Msg  string `json:"msg"`
  }

  func NewCodeError(code int, msg string) error {
      return &CodeError{Code: code, Msg: msg}
  }

  func NewDefaultError(msg string) error {
      return NewCodeError(defaultCode, msg)
  }

  func (e *CodeError) Error() string {
      return e.Msg
  }

  func (e *CodeError) Data() *CodeErrorResponse {
      return &CodeErrorResponse{
          Code: e.Code,
          Msg:  e.Msg,
      }
  }

  • 將登錄邏輯中錯(cuò)誤用CodeError自定義錯(cuò)誤替換

  if len(strings.TrimSpace(req.Username)) == 0 || len(strings.TrimSpace(req.Password)) == 0 {
          return nil, errorx.NewDefaultError("參數(shù)錯(cuò)誤")
      }

      userInfo, err := l.svcCtx.UserModel.FindOneByNumber(req.Username)
      switch err {
      case nil:
      case model.ErrNotFound:
          return nil, errorx.NewDefaultError("用戶(hù)名不存在")
      default:
          return nil, err
      }

      if userInfo.Password != req.Password {
          return nil, errorx.NewDefaultError("用戶(hù)密碼不正確")
      }

      now := time.Now().Unix()
      accessExpire := l.svcCtx.Config.Auth.AccessExpire
      jwtToken, err := l.getJwtToken(l.svcCtx.Config.Auth.AccessSecret, now, l.svcCtx.Config.Auth.AccessExpire, userInfo.Id)
      if err != nil {
          return nil, err
      }

      return &types.LoginReply{
          Id:           userInfo.Id,
          Name:         userInfo.Name,
          Gender:       userInfo.Gender,
          AccessToken:  jwtToken,
          AccessExpire: now + accessExpire,
          RefreshAfter: now + accessExpire/2,
      }, nil

  • 開(kāi)啟自定義錯(cuò)誤

  $ vim service/user/api/user.go
  func main() {
      flag.Parse()

      var c config.Config
      conf.MustLoad(*configFile, &c)

      ctx := svc.NewServiceContext(c)
      server := rest.MustNewServer(c.RestConf)
      defer server.Stop()

      handler.RegisterHandlers(server, ctx)

      // 自定義錯(cuò)誤
      httpx.SetErrorHandler(func(err error) (int, interface{}) {
          switch e := err.(type) {
          case *errorx.CodeError:
              return http.StatusOK, e.Data()
          default:
              return http.StatusInternalServerError, nil
          }
      })

      fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
      server.Start()
  }

  • 重啟服務(wù)驗(yàn)證

  $ curl -i -X POST \
    http://127.0.0.1:8888/user/login \
    -H 'content-type: application/json' \
    -d '{
          "username":"1",
          "password":"123456"
  }'
  HTTP/1.1 200 OK
  Content-Type: application/json
  Date: Tue, 09 Feb 2021 06:47:29 GMT
  Content-Length: 40

  {"code":1001,"msg":"用戶(hù)名不存在"}


以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)