golang-recover错误
目录
golang recover错误
可以 recover
的错误
- 显式触发的
panic
通过panic("error message")
主动抛出的错误,只要在 同一goroutine 的defer
链中调用recover
,即可捕获并恢复。
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered:", r)
}
}()
panic("user-triggered panic")
- 运行时错误(部分)
如切片越界、类型断言失败、空指针解引用等运行时
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
- 自定义类型错误
通过
panic
抛出自定义类型(如结构体或错误接口),recover
可以捕获并处理。
panic(fmt.Errorf("custom error"))
不能 recover
的错误
- 其他goroutine未处理的
panic
每个goroutine需独立处理自己的panic
。若某goroutine未在其内部defer
中调用recover
,该panic
会导致 整个程序崩溃 ,主goroutine无法捕获。
go func() {
panic("goroutine panic") // 主goroutine无法捕获此panic
}()
- 程序已终止的情况
若已调用
os.Exit()
或发生致命错误(如内存耗尽),recover
无法恢复。 - 非
defer
上下文中的panic
recover
仅在defer
函数中调用有效,且必须位于触发panic
的同一函数调用栈中。
func main() {
panic("panic outside defer") // 无法被后续的defer捕获
defer func() { recover() }() // 此处defer不会执行
}
- 重复调用
panic
若在defer
中再次触发panic
且未被捕获,程序仍会崩溃。
defer func() {
recover()
panic("re-panic") // 未被捕获,导致程序终止
}()
panic("initial panic")
- CGO或系统级错误(部分)
某些底层系统错误(如栈溢出、内存段错误)可能绕过Go的
panic/recover
机制,直接终止程序。
关键规则总结
- 作用域限制
recover
仅在当前goroutine的defer
函数中有效。 - 运行时错误的可恢复性 技术上可捕获,但程序状态可能损坏,需谨慎处理。
- 设计建议
- 仅对可预测的错误使用
panic/recover
(如输入验证失败)。 - 避免依赖
recover
处理不可恢复错误(如内存越界),应确保程序健壮性。
通过合理使用
defer
和
recover
,可以优雅处理局部错误,但需理解其局限性以避免误用。