程序在运行过程中遇到异常情况,该如何有效处理呢?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1692个文字,预计阅读时间需要7分钟。
一、整体规范+按错误类型分类,常见的处理方式如下:
+ 错误类型 + 范围 + 处理方式 + 操作员错误 + 与人机界面交互时,不满足输入规则、输入范围等发生的错误 + 测试用户输入 + 提示正确规则 + 强制
一、整体规范
- 按照错误类型,通常的处理方式如下:
错误类型
范围
处理方式
操作员错误
与人机界面交互时不满足输入规则、输入范围等发生的错误
- 校验用户输入
- 提示正确规则
- 强制其改正
运行时错误
与外部资源交互时发生的错误,如网络、文件系统、数据库、其它业务应用系统等
- 记录并抛出异常
- 其它详见“异常处理规范”
程序员错误
与客户模块交互时不满足前置条件后置条件发生的错误,如类库被其他程序员调用时参数超出范围等
- 使用断言
- 按照调用类型,通常的处理方式如下:
调用类型
处理方式
同步调用
- 对有能力处理的异常,捕获并处理之
- 对原始信息过于技术化的异常,捕获并包装之,重新抛出
- 在调用的中间层,对未知异常保持沉默
- 在调用的最高层,必须捕获所有异常,避免本身进程或宿主进程崩溃
- 其它详见“异常处理规范”
异步调用
- 异步调用一般不应有任何返回值
- 服务方最好以同样的方式返回正常信息和错误信息,即正常信息是通过通知的方式返回的话,错误信息也应该通过通知的方式返回;正常信息是通过主动查询得到的话,错误信息也应该通过主动查询得到
二、异常处理规范
异常应该是分层的
异常定义
- 每个模块应该有自己的应用程序异常类型层次,从本模块主动抛出的应用程序异常都应该属于该异常类型层次,客户代码可以只捕捉该层次的基类(?)
- 应用程序的所有自定义异常都应该从开发平台提供的“应用程序异常基类”派生
- 中间件等平台程序的运行时异常都应该从开发平台提供的“运行时异常基类”派生(?)
- 中间件等平台程序的运行时错误都应该从开发平台提供的“错误基类”派生(?)
异常捕获
- 对有能力处理的异常,捕获并处理之
- 在调用的中间层,对未知异常保持沉默
- 在调用的最高层,必须捕获所有异常,避免本身进程或宿主进程崩溃
- 记录捕获到的每个原始异常的信息
异常抛出
- 每个模块应使用本模块所能得知的最精确的错误原因报告异常信息
- 如果有原始异常,在重新抛出的自定义异常中附加原始异常的信息
三、几点说明
错误处理与日志系统
- 错误处理不等同于日志系统,日志系统只是错误信息的一种记录手段
- 错误信息的输出应全部调用日志系统来完成
程序员错误与运行时错误
- 接口函数的前置条件,应该是一种规范,是客户程序员必须遵守的约定;客户程序员违反了约定,程序将产生异常或不可预知的错误;对于这类约定,不应该需要有运行时的代码检查 ;比如如果你的接口函数的一个参数不能为null,而你在函数开始部分程序里写:
if (xxx == null
throw new
}
你的代码实际上允许该参数为null,因为你对null的情况进行了运行时
- 当你对参数没有任何检查就进行了使用,而非法的参数值导致了错误,此时有两种情况: 如果你在接口函数说明里列出了参数不允许的非法取值,那么客户程序员应该修改程序避免传入非法值,该类错误称为程序员错误;如果你没有说明,那么你应该修改函数,处理非法参数
- 不 是所有的限制条件在文档里说明一下,就可以把责任扔给客户程序员了,有一些错误必须处理:特别是客户程序员不需要import你的package就可以和 你的接口交互的情况,如socket服务器 ,你必须在socket服务程序内部检查所有接收到的数据,拒绝错误的请求,否则极易遭到攻击
错误代码与异常
- 不应该使用bool值来返回成功与否,bool返回值只应用在真正查询bool状态的操作中,如 bool IsDirty (),bool hasNext
- 整形或bool型的错误代码返回值强迫客户程序员检查每一次调用,应用异常取代之
四、附录
Anders Hejlsberg谈C#异常设计
- 对 Checked Exceptions
(译者注:在写一段程序时,如果没有用 try-catch 捕捉异常或者显式的抛出异常,而希望程序自动抛出,一些语言的编译器不会允许编译通过,如 Java 就是这样。这就是 Checked Exceptions 最基本的意思。该特性的目的是保证程序的安全性和健壮性。 Zee&Snakey(MVP) 对此有一段很形象的话,可以参见: www.1234xp.com/xiangshui.html 复制请保留原URL】
本文共计1692个文字,预计阅读时间需要7分钟。
一、整体规范+按错误类型分类,常见的处理方式如下:
+ 错误类型 + 范围 + 处理方式 + 操作员错误 + 与人机界面交互时,不满足输入规则、输入范围等发生的错误 + 测试用户输入 + 提示正确规则 + 强制
一、整体规范
- 按照错误类型,通常的处理方式如下:
错误类型
范围
处理方式
操作员错误
与人机界面交互时不满足输入规则、输入范围等发生的错误
- 校验用户输入
- 提示正确规则
- 强制其改正
运行时错误
与外部资源交互时发生的错误,如网络、文件系统、数据库、其它业务应用系统等
- 记录并抛出异常
- 其它详见“异常处理规范”
程序员错误
与客户模块交互时不满足前置条件后置条件发生的错误,如类库被其他程序员调用时参数超出范围等
- 使用断言
- 按照调用类型,通常的处理方式如下:
调用类型
处理方式
同步调用
- 对有能力处理的异常,捕获并处理之
- 对原始信息过于技术化的异常,捕获并包装之,重新抛出
- 在调用的中间层,对未知异常保持沉默
- 在调用的最高层,必须捕获所有异常,避免本身进程或宿主进程崩溃
- 其它详见“异常处理规范”
异步调用
- 异步调用一般不应有任何返回值
- 服务方最好以同样的方式返回正常信息和错误信息,即正常信息是通过通知的方式返回的话,错误信息也应该通过通知的方式返回;正常信息是通过主动查询得到的话,错误信息也应该通过主动查询得到
二、异常处理规范
异常应该是分层的
异常定义
- 每个模块应该有自己的应用程序异常类型层次,从本模块主动抛出的应用程序异常都应该属于该异常类型层次,客户代码可以只捕捉该层次的基类(?)
- 应用程序的所有自定义异常都应该从开发平台提供的“应用程序异常基类”派生
- 中间件等平台程序的运行时异常都应该从开发平台提供的“运行时异常基类”派生(?)
- 中间件等平台程序的运行时错误都应该从开发平台提供的“错误基类”派生(?)
异常捕获
- 对有能力处理的异常,捕获并处理之
- 在调用的中间层,对未知异常保持沉默
- 在调用的最高层,必须捕获所有异常,避免本身进程或宿主进程崩溃
- 记录捕获到的每个原始异常的信息
异常抛出
- 每个模块应使用本模块所能得知的最精确的错误原因报告异常信息
- 如果有原始异常,在重新抛出的自定义异常中附加原始异常的信息
三、几点说明
错误处理与日志系统
- 错误处理不等同于日志系统,日志系统只是错误信息的一种记录手段
- 错误信息的输出应全部调用日志系统来完成
程序员错误与运行时错误
- 接口函数的前置条件,应该是一种规范,是客户程序员必须遵守的约定;客户程序员违反了约定,程序将产生异常或不可预知的错误;对于这类约定,不应该需要有运行时的代码检查 ;比如如果你的接口函数的一个参数不能为null,而你在函数开始部分程序里写:
if (xxx == null
throw new
}
你的代码实际上允许该参数为null,因为你对null的情况进行了运行时
- 当你对参数没有任何检查就进行了使用,而非法的参数值导致了错误,此时有两种情况: 如果你在接口函数说明里列出了参数不允许的非法取值,那么客户程序员应该修改程序避免传入非法值,该类错误称为程序员错误;如果你没有说明,那么你应该修改函数,处理非法参数
- 不 是所有的限制条件在文档里说明一下,就可以把责任扔给客户程序员了,有一些错误必须处理:特别是客户程序员不需要import你的package就可以和 你的接口交互的情况,如socket服务器 ,你必须在socket服务程序内部检查所有接收到的数据,拒绝错误的请求,否则极易遭到攻击
错误代码与异常
- 不应该使用bool值来返回成功与否,bool返回值只应用在真正查询bool状态的操作中,如 bool IsDirty (),bool hasNext
- 整形或bool型的错误代码返回值强迫客户程序员检查每一次调用,应用异常取代之
四、附录
Anders Hejlsberg谈C#异常设计
- 对 Checked Exceptions
(译者注:在写一段程序时,如果没有用 try-catch 捕捉异常或者显式的抛出异常,而希望程序自动抛出,一些语言的编译器不会允许编译通过,如 Java 就是这样。这就是 Checked Exceptions 最基本的意思。该特性的目的是保证程序的安全性和健壮性。 Zee&Snakey(MVP) 对此有一段很形象的话,可以参见: www.1234xp.com/xiangshui.html 复制请保留原URL】

