目录

golang-recover错误

golang recover错误

可以 recover 的错误

  1. 显式触发的 panic 通过 panic("error message") 主动抛出的错误,只要在 同一goroutinedefer 链中调用 recover ,即可捕获并恢复。
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered:", r)
}
}()
panic("user-triggered panic")
  1. 运行时错误(部分) 如切片越界、类型断言失败、空指针解引用等运行时 panic ,只要在 defer 中正确使用 recover技术上可以捕获 。但程序可能处于不可信状态,继续执行需谨慎。
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from runtime error:", r)
}
}()
var a []int
fmt.Println(a[10]) // 越界访问,触发panic
  1. 自定义类型错误 通过 panic 抛出自定义类型(如结构体或错误接口), recover 可以捕获并处理。
panic(fmt.Errorf("custom error"))

不能 recover 的错误

  1. 其他goroutine未处理的 panic 每个goroutine需独立处理自己的 panic 。若某goroutine未在其内部 defer 中调用 recover ,该 panic 会导致 整个程序崩溃 ,主goroutine无法捕获。
go func() {
panic("goroutine panic") // 主goroutine无法捕获此panic
}()
  1. 程序已终止的情况 若已调用 os.Exit() 或发生致命错误(如内存耗尽), recover 无法恢复。
  2. defer 上下文中的 panic recover 仅在 defer 函数中调用有效,且必须位于触发 panic 的同一函数调用栈中。
func main() {
panic("panic outside defer") // 无法被后续的defer捕获
defer func() { recover() }() // 此处defer不会执行
}
  1. 重复调用 panic 若在 defer 中再次触发 panic 且未被捕获,程序仍会崩溃。
defer func() {
recover()
panic("re-panic") // 未被捕获,导致程序终止
}()
panic("initial panic")
  1. CGO或系统级错误(部分) 某些底层系统错误(如栈溢出、内存段错误)可能绕过Go的 panic/recover 机制,直接终止程序。

关键规则总结

  1. 作用域限制 recover 仅在当前goroutine的 defer 函数中有效。
  2. 运行时错误的可恢复性 技术上可捕获,但程序状态可能损坏,需谨慎处理。
  3. 设计建议
  • 仅对可预测的错误使用 panic/recover (如输入验证失败)。
  • 避免依赖 recover 处理不可恢复错误(如内存越界),应确保程序健壮性。

通过合理使用 deferrecover ,可以优雅处理局部错误,但需理解其局限性以避免误用。