关于后端:Go-错误处理用-panic-取代-err-nil-的模式

4次阅读

共计 1757 个字符,预计需要花费 5 分钟才能阅读完成。

若有任何问题或倡议,欢送及时交换和碰撞。我的公众号是【脑子进煎鱼了】,GitHub 地址:https://github.com/eddycjy。

前段时间我分享了文章《先睹为快,Go2 Error 的挣扎之路》后,和一位敌人进行了一次深度交换,他给我分享了他们项目组对于 Go 错误处理的形式调整。

简略来讲,就是在业务代码中应用 panic 的形式来代替“永无止境”的 if err != nil。这就是明天本文的重点内容,咱们一起来看看是怎么做,又有什么优缺点。

为什么想替换

在 Go 语言中 if err != nil 写的太多,还要管办法申明各种,嫌麻烦又不不便:

err := foo()
if err != nil {
     //do something..
     return err
}

err := foo()
if err != nil {
     //do something..
     return err
}

err := foo()
if err != nil {
     //do something..
     return err
}

err := foo()
if err != nil {
     //do something..
     return err
}

上述还是示例代码,比拟直面。若是在工程实际,还得各种 package 跳来跳去加 if err != nil,总的来讲比拟繁琐,要去关怀整体的上下游。更具体的就不赘述了,能够翻看我先前的文章。

怎么替换 err != nil

不想写 if err != nil 的代码,形式之一就是用 panic 来代替他。示例代码如下:

func GetFish(db *sql.DB, name string) []string {rows, err := db.Query("select name from users where `name` = ?", name)
    if err != nil {panic(err)
    }
    defer rows.Close()

    var names []string
    for rows.Next() {
        var name string
        err := rows.Scan(&name)
        if err != nil {panic(err)
        }

        names = append(names, name)
    }

    err = rows.Err()
    if err != nil {panic(err)
    }

    return names
}

在上述业务代码中,咱们通过 panic 的形式取代了 return err 的函数返回,天然其所关联的上游业务代码也就不须要编写 if err != nil 的代码:

func main() {fish1 := GetFish(db, "煎鱼")
    fish2 := GetFish(db, "咸鱼")
    fish3 := GetFish(db, "摸鱼")
    ...
}

同时在转换为应用 panic 模式的谬误机制后,咱们必须要在外层减少 recover 办法:

func AppRecovery() gin.HandlerFunc {return func(c *gin.Context) {defer func() {if err := recover(); err != nil {if _, ok := err.(AppErr); ok {// do something...} else {panic(err)
                }
            }
        }()}
}

每次 panic 后依据其抛出的谬误进行断言,辨认是否定制的 AppErr 谬误类型,若是则能够进行一系列的解决动作。否则可持续向上 panic 抛出给顶级的 Recovery 办法进行解决。

这就是一个绝对残缺的 panic 谬误链路解决了。

优缺点

  • 从长处上来讲:

    • 整体代码构造看起来更加的简洁,仅专一于实现逻辑即可。
    • 不须要关注和编写繁杂的 if err != nil 的错误处理代码。
  • 从毛病上来讲:

    • 认知累赘的减少,须要加入我的项目的每一个新老同学都分明该模式,要做一个根本标准或培训。
    • 存在肯定的性能开销,每次 panic 都存在用户态的上下文切换。
    • 存在肯定的风险性,一旦 panic 没有 recover 住,就会导致事变。
    • Go 官网并不举荐,与 panic 自身的定义相违反,也就是 panicerror 的概念混同。

总结

在明天这篇文章给大家分享了如何应用 panic 的形式来解决 Go 的谬误,其必然无利必有有弊,须要做一个衡量了。

你们团队有没有为了 Go 错误处理做过什么新的调整呢?欢送在留言区交换和分享。

我的公众号

分享 Go 语言、微服务架构和奇怪的零碎设计,欢送大家关注我的公众号和我进行交换和沟通。

最好的关系是相互成就 ,各位的 点赞 就是煎鱼创作的最大能源,感激反对。

正文完
 0