正如反对 panic 的决定中所述,标准的错误处理应该围绕错误返回值进行结构化。库应该倾向于向调用者返回错误,而不是中止程序,特别是对于瞬时错误。
偶尔有必要对一个不变量进行一致性检查,如果违反了这个不变量,就终止程序。一般来说,只有当不变量检查失败意味着内部状态已经无法恢复时,才会这样做。在谷歌代码库中,最可靠的方法是调用log.Fatal
。在这种情况下使用panic
是不可靠的,因为延迟函数有可能会出现死锁或进一步破坏内部或外部状态。
同样,抵制恢复 panic 以避免崩溃的诱惑,因为这样做可能导致传播损坏的状态。你离 panic 越远,你对程序的状态就越不了解,它可能持有锁或其他资源。然后,程序可以发展出其他意想不到的故障模式,使问题更加难以诊断。与其试图在代码中处理意外的 panic,不如使用监控工具来浮现出意外的故障,并高度优先修复相关的错误。
注意:标准的net/http
服务器违反了这个建议,从请求处理程序中恢复 panic。有经验的 Go 工程师的共识是,这是一个历史性的错误。如果你对其他语言的应用服务器的日志进行采样,通常会发现有大量的堆栈轨迹没有被处理。在你的服务器中应避免这种陷阱。