我们都知道golang 中 recover函数是用来捕捉异常从panic中恢复过来。但是如果设置不当会造成捕捉异常失败!看如下例子:

错误示例1:

 // 错误的: 在同一个函数栈中,recover不起做用
if r:=recover();r!=nil{
   log.Fatal(r)
}
panic(123)  

错误示例2:

 // 错误: 隔了两个函数栈!
defer func(){
   defer func(){
      // 无法捕获异常
      if r := recover();r!=nil{
         fmt.Println(r)
      }
   }()
}()

panic(1)  

错误示例3:

 // 错误: 捕获失败! 因为隔了两个函数栈
func main(){
  defer func(){
   if r:=MyRecover();r!=nil{
      fmt.Println(r)
   }
}()
panic(1)
}

func MyRecover() interface{}{
log.Println("Trace...")
return recover()
}  

正确示例:

 func main(){
defer MyRecover()
  panic(1)
}
func MyRecover() interface{}{
log.Println("Trace...")
return recover()
}  

or:

 // 正确的: 隔且只隔一个栈
defer func(){
   if r := recover();r!=nil{
      fmt.Println("错误信息:",r)
   }
}()
panic(1)  

总结要点:

1. 当panic 与 recover 在同一个函数栈中,recover不能正常捕获异常!

2. 当panic 与 recover 相隔两个函数栈,recover不能正常捕获异常!

3. 当panic 与 recover只相隔一个函数栈时,recover能正常捕获异常!