开发者

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

目录
  • 正文
  • 一,正常情况下
  • 二, 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(){
dandroideferfunc(){
iferr:=recover();err!=nil{开发者_JS学习
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:/goProj编程ect/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会失效的情况。

  •  携程编程客栈中出现panic
  • defer不直接调用recover
  • panic的值为nil值

写代码的时候需要注意避免因为这几种情况的出现而导致服务不可用。以上就是golang新手常遇见的一些坑。

以上就是golang recover函数使用中的一些坑解析的详细内容,更多关于golang recover函数坑的资料请关注我们其它相关文章!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新开发

开发排行榜