Go高级特性探究之recover捕获panic详解

 更新时间:2023年06月06日 11:01:41   作者:tracy小猫  
在Go语言中,当程序出现panic(即运行时错误)时,程序会立即停止当前的执行流程,而recover函数的作用就是捕获这个panic,下面就来看看具体是怎么操作的吧

在Go语言中,当程序出现panic(即运行时错误)时,程序会立即停止当前的执行流程,并在函数调用堆栈向上逐层返回,直到遇到recover函数或程序终止为止。

而recover函数的作用就是捕获这个panic,并恢复正常的执行流程。在Gin框架中,提供了recover中间件来自动捕获panic,并转换为HTTP 500错误返回给客户端。

使用

使用recover中间件非常简单,只需要在Gin路由中添加即可:

router := gin.Default()
router.Use(gin.Recovery())

需要注意的是,recover中间件应该在Gin路由中的第一个声明,以确保可以捕获所有的panic。

配合日志打印与埋点上报

在API开发中,当用户请求接口时,有时候会遇到一些问题,如访问url错误、参数错误、数据库连接超时等。虽然recover中间件可以避免由程序错误导致的panic,但仍然需要记录这些错误信息来协助问题的排查和定位。

因此,我们可以配合日志打印和埋点上报来记录这些错误。以日志打印为例,Gin框架提供了官方的Logger中间件,可以使用Logger来记录错误信息:

router := gin.Default()
// Logger 中间件将请求的URL、响应时间、响应状态码和请求的IP地址写入日志文件
router.Use(gin.Logger())
// Recover 中间件将 panic 转换为 500 错误,并写入日志文件
router.Use(gin.Recovery())
// 业务代码
router.GET("/api", func(c \*gin.Context) {
    // code
    if err != nil {
        // 某个函数抛出了 panic
        log.Printf("\[ERROR] - %v\n", err)
        c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
            "message": "内部错误,请稍后重试",
        })
        return
    }
    // code
})

在上述代码中,我们使用log来记录错误信息,并在响应中返回了错误提示。这样我们就能及时的发现问题并进行排查了。

当然,我们还可以在记录错误信息的同时上传到埋点工具中,例如Sentry、Zipkin等,来实现自动的错误上报和监控。

recover在开源项目中的使用

recover中间件在开源项目中广泛应用,例如Prometheus、etcd、Kubernetes等项目中都有使用。

以etcd为例,它使用recover中间件捕获所有的panic,并在日志中记录错误信息,如下所示:

func (s *EtcdServer) recoverAndLog(rctx rpctypes.Context, w http.ResponseWriter, req *http.Request) {
    data, err := ioutil.ReadAll(req.Body)
    if err != nil {
        writeError(w, rctx, err)
        return
    }
    defer func() {
        if v := recover(); v != nil {
            log.Printf("panic: %v", v)
            writeError(w, rctx, fmt.Errorf("panic: %v", v))
        }
    }()
    // code
}

在该函数中,使用了defer关键字调用recover函数捕获panic,并使用log记录错误信息并返回错误提示。

总结

通过Gin框架中的recover中间件,我们可以方便的捕获和处理程序运行时的错误,从而提高了API服务的稳定性和可靠性。同时,配合日志打印和埋点上报,可以更好地记录错误信息和辅助问题的排查和解决。在开源项目中,recover中间件也被广泛应用,并帮助了很多项目实现了稳定的运行。

到此这篇关于Go高级特性探究之recover捕获panic详解的文章就介绍到这了,更多相关Go recover捕获panic内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • goland 导入github包报红问题解决

    goland 导入github包报红问题解决

    本文主要介绍了Go项目在GoLand中导入依赖标红问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08
  • golang 切片的三种使用方式及区别的说明

    golang 切片的三种使用方式及区别的说明

    这篇文章主要介绍了golang 切片的三种使用方式及区别的说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • Go语言中struct的匿名属性特征实例分析

    Go语言中struct的匿名属性特征实例分析

    这篇文章主要介绍了Go语言中struct的匿名属性特征,实例分析了struct的匿名属性特征,对于深入学习Go语言程序设计具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • 解决golang sync.Wait()不执行的问题

    解决golang sync.Wait()不执行的问题

    这篇文章主要介绍了解决golang sync.Wait()不执行的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • 详解Golang并发操作中常见的死锁情形

    详解Golang并发操作中常见的死锁情形

    在Go的协程里面死锁通常就是永久阻塞了,本文主要介绍了Golang并发操作中常见的死锁情形,具有一定的参考价值,感兴趣的可以了解一下
    2021-09-09
  • 深入理解go sync.Waitgroup的使用

    深入理解go sync.Waitgroup的使用

    WaitGroup在go语言中,用于线程同步,本文主要介绍了深入理解go sync.Waitgroup的使用,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • Go语言中的字符串拼接方法详情

    Go语言中的字符串拼接方法详情

    本文介绍Go语言中的string类型、strings包和bytes.Buffer类型,介绍几种字符串拼接方法的相关资料,需要的朋友可以参考一下,希望对你有所帮助
    2021-10-10
  • 一文搞懂Golang 时间和日期相关函数

    一文搞懂Golang 时间和日期相关函数

    这篇文章主要介绍了Golang 时间和日期相关函数,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • 详解Golang中SQLX库的高级操作

    详解Golang中SQLX库的高级操作

    sqlx是Golang中的一个知名三方库,其为Go标准库database/sql提供了一组扩展支持,下面就来和大家分享一下SQLX库的高级操作吧,希望对大家有所帮助
    2023-06-06
  • go语言环境变量设置全过程

    go语言环境变量设置全过程

    这篇文章主要介绍了go语言环境变量设置全过程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05

最新评论