以下是根据刘未鹏的错误处理(Error-Handling):为何、何时、如何(rev#2)整理而来
  动机:为什么要进行错误处理
  错误发生时,能恢复的要恢复。不能恢复的话,要保存用户数据,释放资源。可以得话需要记录日志、错误报告,重启程序。
  什么是错误?
  配置文件语法错误,文件由于访问权限无法打开,读写。网络连接失败,断开连接。数据库连接失败。
  一个函数得前置条件无法得到满足,或者后置条件无法满足,无法维持其中的循环不变量(invariants)
  什么不是错误?
  1) 用于表示状态的结果不能算做错误,只是程序逻辑分支的一部分,它是一种状态码(status-code)。
  如  if(foo(...)) {...}
  else {...}
  或
  while(foo(...)) {...}
  2)有一些“可恢复错误”,并不能算作真正的错误。
  它一旦发生会转入一个错误恢复的子过程,后者尽量恢复主干程序所需要的前置条件。如果不能恢复的话,变成了一个实在的错误
  例如:读取一个配置文件失败,会去创建一个默认的配置文件。
  如果无法恢复成功,也会转入第二个分支,虽然结果不能“完美执行”。例如内存申请失败,给出的错误提示。
  3)因为代码bug导致无法满足某个invariants,不是错误。
  经常出现的不是错误,它可能是一个分支逻辑,或是存在bug。
  异常(exception) vs 错误码(error-code)
  使用error-code 的问题
  异常是跨越调用栈的,error-code需要一层层传播
  1 麻烦,需要不断的向上层栈传播
  2 不优雅且不可伸缩,代码嵌套过多,重复代码
  使用异常

 

void foo()
{
try{
op1;
op2;
...
} catch (...){
//log
//clean up
throw;
}
}

  使用error-code

 

int foo()
{
if(!op1()) goto FAILED;
if(!op2()) goto FAILED;
return SUCCEEDED;
FAILED:
//log, clean up
return FAILED;
}