zoukankan      html  css  js  c++  java
  • Golang中使用recover捕获panic的操作及遇到的一个坑

    说明

      本文介绍一下使用recover捕获panic的操作及遇到的一个坑。

    使用recover捕获panic

      正常情况下,发生panic的函数会导致程序异常退出,我们可以使用defer语句在另外一个函数中捕获到当前函数panic的error并做相应的逻辑处理:

    package test1
    
    import (
        "fmt"
        "testing"
    )
    
    func TestRecover(t *testing.T) {
    
        handleSth()
    
    }
    
    // 返回的函数
    func sendResponse(err string) {
        // 有错误返回错误信息
        if err != "" {
            fmt.Println("发生异常:", err)
        } else {
            println("成功sendResponse")
        }
    }
    
    // 专门用于捕获异常的
    func rec1() {
        err := recover()
        // 注意这里捕获到的err是一个interface,需要与nil做比较
        if err != nil {
            sendResponse(err.(string))
        } else {
            sendResponse("")
        }
    }
    
    // 业务代码,可能发生异常
    func handleSth() {
    
        // 如果函数中发生了异常会被rec1()函数捕获到
        defer rec1()
        // 模拟业务代码中发生panic的情况
        panic("发生了异常...")
    
    }

    遇到的问题

    正确的方式

      正常情况下,我们使用下面的方式去捕获panic:

    package test1
    
    import (
        "fmt"
        "testing"
    )
    
    func rec1() {
        err :=  recover()
        if err != nil{
            fmt.Println("err: ", err)
        }
    }
    
    func TestRecover(t *testing.T) {
    
        // 正确的捕获方式
        defer rec1()
    
        panic("TestRecover raises error!")
    }

    错误的方式

      下面这种方式捕获不到panic:

    package test1
    
    import (
        "fmt"
        "testing"
    )
    
    func rec1() {
        err :=  recover()
        if err != nil{
            fmt.Println("err: ", err)
        }
    }
    
    
    
    func TestRecover(t *testing.T) {
    
        // 错误的捕获方式
        defer func(){
            // 这里加一些其他的业务逻辑
    rec1() }() panic("TestRecover raises error!") }

      上面这种方法其实是想在recover到panic之前再做一些业务处理,结果没有捕获到想要捕获的panic会导致程序崩溃。

      看了一下相关资料,解释应该是每一个recover应该“直接”与对应的panic配对,也就是说recover应该只能捕获到与其同一个作用域里的panic(具体原理还需要深入学习)。

      像上面的那种写法应该在匿名函数中写panic才可以:

    func TestRecover(t *testing.T) {
        // 错误的捕获方式
        func(){
            // 这里写一些其他的业务逻辑
            defer rec1()
            panic("TestRecover raises error!")
        }()
    }

      关于Golang中defer、panic与recover相关说明的参考:https://huoyingwhw.com/golangGuide/%E5%9F%BA%E7%A1%80/4/#82-defer

  • 相关阅读:
    MySQL管理工具-SQLyog 9.63的使用详解
    通讯录管理系统
    Mavenx学习找对方法,快速上手!
    晚风花间寺中人
    PE重装系统,U盘重装系统,一步到位,重装无忧!
    进入博客园的第一篇随笔,贡献给我最喜欢的作家-大冰
    天地有情尽白发,人间无意了沧桑
    狼和羊的故事(安徒生新篇)
    .Net Core CLR GC的浅度分析
    .net core 的夸代扫描标记card_table的细节分析
  • 原文地址:https://www.cnblogs.com/paulwhw/p/14544499.html
Copyright © 2011-2022 走看看