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

时间:2016-01-17 18:58:09

标签: go error-handling stack-trace panic

是否可以从recover“重新抛出”错误并保留原始堆栈跟踪?我所知道的最好的办法就是再次恐慌,但确实会创建一个新的堆栈跟踪。

func do() {
    defer func() {
        cleanUp()
        if x := recover(); x != nil {
            handleError()
            panic(x)
        }
    }()
    doStuff()
}

我想要这样做的动机是,除非我的函数正常退出或handleError运行,否则我的程序会死锁。除非我保留原始的痕迹,否则我不知道它在哪里坠毁。

2 个答案:

答案 0 :(得分:6)

即使他们没有打电话给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

答案 1 :(得分:6)

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

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

func do() {
    panicked := true
    defer func() {
        cleanUp()
        if panicked {
            handleError()
        }
    }()
    doStuff()
    panicked = false
}