异常处理

异常处理

不熟悉erlang,不过joyent这篇讲node.js错误处理的文章挺有let it crash精髓: 《Joyent | Error Handling**

首先文章定义了Operational ErrorsProgrammer Errors

  • Operational Error:表示一个正确的程序在运行时报告的错误;这些错误不是程序本身的bug,而可能是操作系统的报错、网络错误、用户输入不正确、超时、500、内存不足等;
  • Programmer Error:一般属于程序中的bug,比如错误的访问undefined对象、错误的类型传递;

有时两者会出于同一个root cause而一体两面地出现:如果一个服务端出现bug导致崩溃,客户端收到500将视为Operational Error;如果对Operational Error的处理不正确,这也属于Programmer Errror

两者的重要差异在于:Operational Error是一个正确的程序必须要处理的;而Programmer Error属于bug,程序本身并不能处理。

那么遇到Programmer Error应当怎么办呢?这就引出了Let it crash策略。

有些web框架在请求中遇到Programmer Error的异常之后,会吞掉异常继续响应请求,这很常见,但是异常之后可能已经有奇怪的地方变得不一样了:

  • 部分公共状态可能被污染为null、undefined;
  • 数据库连接可能泄露,甚至可能留着一个未关闭的事务;
  • socket可能没有正确关闭;
  • 内存可能泄露;

这些错误往往有累加效应,到最终展露症状时就很难找root cause了。比如,当你数据库被日积月累的连接泄露连爆的时候,引入这个连接泄露的变更在哪个commit

文章认为从Programmer Error恢复的最佳方法便是立即crash,配合一个supervisor之类的restarter,出现问题时立即crash,并重启恢复到一个干净的初始状态。此外,服务端的Programmer Error应被客户端视为Operational Error,客户端应当对此作处理。