前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Golang】基于GoFrame的异常处理实践

【Golang】基于GoFrame的异常处理实践

作者头像
明月AI
发布2024-02-26 09:36:26
1480
发布2024-02-26 09:36:26
举报
文章被收录于专栏:野生AI架构师

第一次基于GoFrame框架开发项目,这是一个灵感来自PHP Laravel的Golang开发框架,使用之后其实自己并不是很喜欢,把一个开发语言的习惯直接迁移到另一个开发语言上,个人觉得并不是一个好主意,不过这次并不想讨论这个。

同事之前的实践

异常处理是每个框架都需要考虑的问题,GoFrame也有自己的设计,可以看他们的官方文档。同事基于自己的实践经验,建议参考:

上面是关于异常的定义,在使用的时候:

这其实就是仿照其他语言的抛出异常,然后在外部使用Try语句进行捕获,这确实是可以的,不过这并不是Golang所提倡的。Golang之所以没有实现类似其他语言的try catch语句,是有自己的考量的,它是希望所有异常都能得到显式的处理,于是都是采用return返回的形式,有时这写法确实挺啰嗦,但这不失为一种好习惯。

另外,如果异常文本都完全跟异常code值绑定在一起,有时就比较难区分,例如“json字符串解释错误”,如果系统中很多地方都有这个错误,可能这个异常信息对于排查问题就不是很直接。

我的实现

基于以上的考虑,最终关于异常的定义:

定义了一个Code的错误代码类型。

配套工具函数:

代码语言:javascript
复制
package utils

import (
  "fmt"

  "git.ibbd.net/ai/knowledge-base-backend/v1/internal/consts"
  "github.com/gogf/gf/v2/errors/gcode"
  "github.com/gogf/gf/v2/errors/gerror"
)

// 错误信息包装
// 避免错误信息被重复包装
func ErrorWrap(code consts.Code, err error) error {
  if _, ok := err.(*gerror.Error); ok {
    return err
  }
  return errorWrap(code, err)
}

// 格式化自定义错误
func Errorf(code consts.Code, format string, a ...interface{}) error {
  err := fmt.Errorf(format, a...)
  return errorWrap(code, err)
}

func errorWrap(code consts.Code, err error) error {
  msg := fmt.Sprintf("%s: %s", consts.ErrMessages[code], err.Error())
  codeObj := gcode.New(int(code), msg, "")
  return gerror.NewCode(codeObj, codeObj.Message())
}

主要是两个包装函数:

  • Errorf:使用字符串生成error;
  • ErrorWrap:对本身已经是error的变量进行包装,如果本身已经是gerror.Error类型的,则直接返回,避免在传递过程中被重复包装;

使用样例代码大概如下:

代码语言:javascript
复制
func (s *sApplication) CheckMatchWithClass(ctx context.Context, appId, appSecret string) (err error) {
  count, err := dao.Application.Ctx(ctx).
    Where(dao.Application.Columns().Id, appId).
    Where(dao.Application.Columns().Password, appSecret).
    Where(dao.Application.Columns().Class, appClass).
    Count()
  if err != nil {
    err = utils.Errorf(consts.CodeDbOperation, "应用ID与密钥匹配SQL异常, app id: %s, app secret: %s, err: %s", appId, appSecret, err)
    return
  }
  if count != 1 {
    err = utils.Errorf(consts.CodeAppNotMatch, "应用ID与应用密钥不匹配(注意应用状态及应用类似是否匹配), app id: %s, app secret: %s", appId, appSecret)
    return
  }
  return
}

这应该才是比较Golang的方式。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-02-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 野生AI架构师 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档