为了账号安全,请及时绑定邮箱和手机立即绑定

我可以从恐慌中恢复,处理错误,然后再次恐慌并保留原始堆栈跟踪吗?

我可以从恐慌中恢复,处理错误,然后再次恐慌并保留原始堆栈跟踪吗?

Go
慕丝7291255 2021-12-07 10:52:48
是否可以“重新抛出”错误recover并保留原始堆栈跟踪?我知道怎么做的最好的方法是再次恐慌,但这确实会创建一个新的堆栈跟踪。func do() {    defer func() {        cleanUp()        if x := recover(); x != nil {            handleError()            panic(x)        }    }()    doStuff()}我想要这个的动机是,除非我的函数正常退出或handleError运行,否则我的程序会死锁。除非我保留原来的 strack 痕迹,否则我不知道它在哪里坠毁。
查看完整描述

2 回答

?
波斯汪

TA贡献1811条经验 获得超4个赞

解决方案是不调用recover,因为这样既不可能重新抛出也不访问堆栈跟踪。使用 bool 标志而不是recover检查恐慌。


https://play.golang.org/p/PKeP9s-3tF


func do() {

    panicked := true

    defer func() {

        cleanUp()

        if panicked {

            handleError()

        }

    }()

    doStuff()

    panicked = false

}


查看完整回答
反对 回复 2021-12-07
?
慕仙森

TA贡献1827条经验 获得超7个赞

堆栈中更高层的延迟函数将在恐慌时运行,即使它们不调用recover().


只需删除 if 语句和重新恐慌。然后处理你的错误,让恐慌继续向上堆栈。


func do() {

    defer handleError()

    doStuff()

}

一个简单的演示:


https://play.golang.org/p/UiRou5MhUR


func a() {

    defer func() {

        fmt.Println("a")

    }()

    panic("test")

}

func b() {

    defer func() {

        fmt.Println("b")

    }()

}


func main() {

    fmt.Println("Hello, playground")

    b()

}

输出


Hello, playground

b


查看完整回答
反对 回复 2021-12-07
  • 2 回答
  • 0 关注
  • 163 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信