[PHP] golang recover函数使用中的一些坑解析

2449 0
王子 2023-2-25 14:49:22 | 显示全部楼层 |阅读模式
目录

    正文一,正常情况下二, goroutine中panic 三,间接调用recover四,nil panic五,总结


正文



众所周知golang 中recover函数可以捕捉panic,防止在出现异常的情况下服务整个不可用。然而某些情况下recover也无法catch panic。下面就会说一些这些情况。

一,正常情况下

packagemain
import"fmt"
funcmain(){
deferfunc(){
iferr:=recover();err!=nil{
fmt.Printf("err=%v",err)
}
}()
panic("apanic")
}
打印结果:
err=apanic
Processfinishedwithexitcode0
能正常catch panic

二, goroutine中panic

之前线上环境出现过接口出现panic导致服务不可用的情况,于是同事就直接在main函数加了个recover认为万事无忧了。实际上recover并不能捕捉到协程中的panic。
packagemain
import"fmt"
funcmain(){
deferfunc(){
iferr:=recover();err!=nil{
fmt.Printf("err=%v",err)
}
}()
gofunc(){
panic("apanic")
}()
select{}
}
打印结果:
panic:apanic
goroutine6[running]:
main.main.func2()
I:/goProject/catchPanic.go:13+0x40
createdbymain.main
I:/goProject/catchPanic.go:12+0x5e
实际上还是会panic导致服务不可用。
正确写法
packagemain
import"fmt"
funcmain(){
gofunc(){
deferfunc(){
iferr:=recover();err!=nil{
fmt.Printf("err=%v",err)
}
}()
panic("apanic")
}()
select{}
}
返回值:
fatalerror:allgoroutinesareasleep-deadlock!
goroutine1[select(nocases)]:
main.main()
I:/goProject/catchPanic.go:15+0x41
err=apanic
Processfinishedwithexitcode2
可以看到panic被正常捕捉,同时因为select语句陷入阻塞,报了一个死锁的错。

三,间接调用recover

在我想要把recover封装成成一个函数的时候,发现recover并没有生效,因为recover只有在被defer语句直接调用的时候才会生效。当recover在其他函数内部的时候无法正确捕捉到panic。
packagemain
import"fmt"
funcmain(){
defercover()
panic("apanic")
}
funccover(){
deferfunc(){
iferr:=recover();err!=nil{
fmt.Println(err)
}
}()
}
返回值:
panic:apanic
goroutine1[running]:
main.main()
I:/goProject/catchPanic.go:7+0x62

四,nil panic

panic要被捕捉,还需要满足一种条件,就是panic不是nil panic,否则在进行捕获判断的时候无法知道是panic没有发生还是panic本身就是nil。
例如以下代码
packagemain
import"fmt"
funcmain(){
deferfunc(){
iferr:=recover();err!=nil{
fmt.Println(err)
}
fmt.Println("afterrecover")
}()
panic(nil)
select{}
}
返回值:
afterrecover
recover并没有正确处理异常,因为异常的值为nil。

五,总结

这篇文章讲述了三种recover会失效的情况。
    携程中出现panicdefer不直接调用recoverpanic的值为nil值
写代码的时候需要注意避免因为这几种情况的出现而导致服务不可用。以上就是golang新手常遇见的一些坑。
以上就是golang recover函数使用中的一些坑解析的详细内容,更多关于golang recover函数坑的资料请关注中国红客联盟其它相关文章!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2025 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行