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内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • go语言int64整型转字符串的实现

    go语言int64整型转字符串的实现

    本文主要介绍了go语言int64整型转字符串的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • Golang 标准库 tips之waitgroup详解

    Golang 标准库 tips之waitgroup详解

    本篇文章给大家介绍Golang 标准库 tips之waitgroup的相关知识,包括使用 channel 实现 WaitGroup 的功能介绍,感兴趣的朋友跟随小编一起看看吧
    2021-07-07
  • 深入Golang的接口interface

    深入Golang的接口interface

    这篇文章主要介绍了深入Golang的接口interface,go不要求类型显示地声明实现了哪个接口,只要实现了相关的方法即可,编译器就能检测到,接下来关于接口interface的相关介绍需要的朋友可以参考下面文章内容
    2022-06-06
  • 详解Golang五种原子性操作的用法

    详解Golang五种原子性操作的用法

    本文主要介绍了详解Golang五种原子性操作的用法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • Golang 运算符及位运算详解

    Golang 运算符及位运算详解

    这篇文章主要介绍了Golang 运算符及位运算详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Go语言基础go install命令使用示例详解

    Go语言基础go install命令使用示例详解

    这篇文章主要为大家介绍了Go语言基础go install命令的使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2021-11-11
  • Golang 函数执行时间统计装饰器的一个实现详解

    Golang 函数执行时间统计装饰器的一个实现详解

    这篇文章主要介绍了Golang 函数执行时间统计装饰器的一个实现详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-03-03
  • 详解Go语言如何利用高阶函数写出优雅的代码

    详解Go语言如何利用高阶函数写出优雅的代码

    高阶函数(Hiher-order Function)定义为:满足下列条件之一的函数:接收一个或多个函数作为参数;返回值是一个函数。本文为大家介绍了如何利用高阶函数写出优雅的代码,希望对大家有所帮助
    2023-01-01
  • Go|使用Options模式和建造者模式创建对象实战

    Go|使用Options模式和建造者模式创建对象实战

    这篇文章主要介绍了Go使用Options模式和建造者模式创建对象实战详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • go语言 bool类型的使用操作

    go语言 bool类型的使用操作

    这篇文章主要介绍了go语言 bool类型的使用操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12

最新评论