6. 错误分类
如果你不知道你的程序会导致什么错误或者不了解错误的含义, 那你的应用程序正常工作就是一个巧合.
关于错误与异常:
大部分语言中, 错误和异常是有区别的, 错误通常是特定的错误类型的实例, 有的语言可以用一条错误消息来代替, 错误是一个可以传递的实体; 如果一个错误被抛出了那么它就变成了一个异常.
关于错误的类型
学会对错误进行分类, 进而学习不同类别的错误的处理方式:
- 操作错误(Operational errors)
- 程序员错误(Programmer errors)
操作错误
是正确编写的程序在运行时产生的错误。它并不是程序的Bug,反而经常是其它问题:系统本身(内存不足或者打开文件数过多),系统配置(没有到达远程主机的路由),网络问题(端口挂起),远程服务(500错误,连接失败). 例子如下:
- 连接不到服务器
- 无法解析主机名
- 无效的用户输入
- 请求超时
- 服务器返回500
- 套接字被挂起
- 系统内存不足
程序员错误
是程序里的Bug。这些错误往往可以通过修改代码避免。它们永远都没法被有效的处理。比如:
- 读取 undefined 的一个属性
- 调用异步函数没有指定回调
- 该传对象的时候传了一个字符串
- 该传IP地址的时候传了一个对象
这样的区分很重要: 操作失败是程序正常操作的一部分. 而由程序员的失误则是Bug.
对于操作错误, 因为哪里出错和为什么出错决定了影响大小和对策, 主要有以下几种方案:
- 直接处理
- 把出错扩散到客户端
- 重试操作
- 直接崩溃
- 记录错误,其他什么都不做
而对于程序员错误是没有什么好做的, 最好的从错误恢复的方法是立刻崩溃.
以上分类出自 Error Handling in Node.js 虽然这篇文章是讲node.js异常处理, 但是前半部分异常分类以及应对, 其实完全适用于其他平台.
来看看Core Java中对Exception的分类说明:
这个层次结构又分解为两个分支: 一个分支派生于RuntimeException; 另一个分支包含其他异常. 划分两个分支的规则是: 由程序错误导致的异常属于RuntimeException; 而程序本身没有问题, 但由于像IO错误这类问题导致的异常属于其他异常.
如果出现RuntimeException异常, 那么一定是你的问题.
虽然术语不一致, 但可以看出, Core Java中RuntimeException就是程序员错误(Programmer errors), 其他异常属于操作错误(Operational errors). 处理异常的规则完全可以根据异常分类在其他语言平台应用.
再看看 Golang错误和异常处理的正确姿势: http://www.jianshu.com/p/f30da01eea97