最近刚好作了一个产品的异常处理规范,把我做的也拿出来晒晒,和大家讨论一下。
1、CheckException or UnCheckedException
个人倾向用UnCheckedException。我见过的最多的处理异常的代码就是记录日志或转换后抛出,好像做其他操作的少之又少。我以前还见过有人不管三七二十一,抓到什么抛什么,结果一个接口抛出了3-5种CheckException。别扭啊,呵呵。
当然,最大的缺陷就是对接口调用者的使用。至少UnCheckedException可以让接口调用者选择catch还是不catch。
因为这是一个遗留系统,都使用了CheckedException,不过好在使用的比较规范,没有太大麻烦。
2、异常信息
因为开发者众多,异常信息五花八门,有中文的有英文的,有简单的,有复杂的。散落在各个类里,修改起来很麻烦。
我的处理办法是,定义异常码,异常信息和异常码一一对应,定义在properties文件里,抛出异常的地方只引用异常码。这样,如果需要修改异常信息,只要修改properties文件重新打包即可。异常码分为原因码和位置码。位置码一般用在业务逻辑类里。比如一般用到的Facad模式,可能一个接口定义了n个方法,每个方法都抛出XXXBusinessException(XXX用于区分业务子包),抛出的异常码在代码里顺序定义即可。原因码表示某类异常,比如SQLException引起的异常都为8000。
异常码中原因码按包、类、接口定义,比如:前两位表示一级子包,接下来两位留给二级子包,接下来两位表示类,最后3位表示方法。
异常信息如果需要,可以保留现场信息。比如:“用户[abc]已存在”。这样的信息就比“用户已存在”明确。这个功能可以通过java.text.MessageFormat实现。
3、异常的链式抛出
即,在调用底层接口时捕获到异常,需要转成其他的异常抛出时,使用带Throwable的构造器。这样可以保留最原始的出错信息。
异常基类代码:
java 代码
- public class BaseException extends Exception {
-
-
- protected long errorCode;
-
-
- protected String[] args;
-
-
-
-
- public BaseException(long errorCode) {
- super();
- this.errorCode = errorCode;
- }
-
-
-
-
-
- public BaseException(long errorCode,Throwable cause) {
- super(cause);
- this.errorCode = errorCode;
- }
-
-
-
-
-
-
- public BaseException(long errorCode,Throwable cause,String[] args) {
- super(cause);
- this.errorCode = errorCode;
- this.args = args;
- }
-
-
-
-
- public String getMessage() {
- String message = "";
- if (this.args == null || this.args.length == 0) {
- message = MessageSource.getInstance().resolveCodeWithoutArguments(
- this.errorCode);
- } else {
- message = MessageSource.getInstance().resolveCode(this.errorCode)
- .format(this.args);
- }
-
- return this.errorCode+":"+message;
- }
-
-
-
-
- public long getErrorCode() {
- return errorCode;
- }
-
-
-
-
- public String[] getArgs() {
- return args;
- }
-
- }
其中:MessageSource这个类就是根据是否有现场信息,分别处理,得到完整异常信息表述字符串。
关于主贴中嵌套打印的部分,从JDK1.4开始,Throwable就是嵌套打印的,所以不必再覆盖那几个方法了。
现在假使,有AException 和BException,都从BaseException继承。在方法里,我们捕获了AException,需要转换成BException抛出,这时候我们就非常希望能直接用AException的信息(errorCode和args)。所以,如果再来这样一个构造器似乎更好:
java 代码
- public BaseException(BaseException cause){
- this.errorCode = cause.getErrorCode();
- this.args = cause.getArgs();
- }
但是,因为Exception有一个构造器:public Exception(Throwable cause),所以这样的构造器就是重载(overload),而不是覆盖(Override)。重载,入参又是父子类关系,这样的方法很容易混淆,所以就没有提供。
我按照这个异常处理规范,花了两三天时间把代码重构了一遍。似乎用起来挺好使
分享到:
相关推荐
Spring Cloud Gateway的全局异常处理 Spring Cloud Gateway中的全局异常处理不能直接用@ControllerAdvice来处理,通过跟踪异常信息的抛出,找到对应的源码,自定义一些处理逻辑来符合业务的需求。 网关都是给接口做...
C#异常处理总结及简单实例 一、异常处理的理解? 异常处理是指程序在运行过程中,发生错误会导致程序退出,这种错误,就叫做异常。 因此处理这种错误,就称为异常处理。 二、异常处理如何操作? C# 异常处理时建立在...
在开始进行自定义的异常处理逻辑之前,我们有必要看一下异常处理的默认实现。也就是:为什么会产生上面小节提到的现象? ResponseErrorHandler是RestTemplate请求结果的异常处理器接口 o接口的第一个方法hasError...
异常处理.ppt异常处理.ppt异常处理.ppt异常处理.ppt异常处理.ppt异常处理.ppt
课程作业,实现两数计算及其异常处理,异常处理机制能让程序在异常发生时,按照代码的预先设定的异常处理逻辑,针对性地处理异常,让程序尽最大可能恢复正常并继续执行,且保持代码的清晰。 Java中的异常可以是函数...
关于异常处理的word文档 关于异常处理的word文档 关于异常处理的word文档
Springboot全局异常处理demo 项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的、不可预知的异常需要处理。每个过程都单独处理异常,系统的...
主要为大家详细介绍了MySQL定义异常和异常处理,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
2. Microsoft 对异常处理方法的扩展 3. 标准 C++异常处理的基本语法和语义 4. 实例剖析 EH 5. C++的 new 和 delete 操作时的异常处理 6. Microsoft 对于的实现版本中的异常处理 7. 部分构造及 placement delete 8. ...
C++ 异常处理 C++ 异常处理C++ 异常处理C++ 异常处理C++ 异常处理C++ 异常处理C++ 异常处理C++ 异常处理
java异常处理java异常处理java异常处理java异常处理java异常处理java异常处理java异常处理java异常处理java异常处理java异常处理java异常处理java异常处理java异常处理
统一异常处理会区分前端是否ajax请求,自动返回json数据格式,要求开发人员在处理ajax请求时统一封装成一个对象返回,以符合代码统一规范。 此工程在idea环境编写,导入请自己新建工程手工复制代码导入。
ADS异常处理.pptADS异常处理.pptADS异常处理.ppt
ARM异常处理机制ARM异常处理机制ARM异常处理机制ARM异常处理机制ARM异常处理机制ARM异常处理机制ARM异常处理机制ARM异常处理机制ARM异常处理机制
主要介绍了详解SpringCloud Finchley Gateway 统一异常处理,非常具有实用价值,需要的朋友可以参考下
中的异常处理问题显得尤为突出[1-3]。传统上将异常处理包含于正常流程中的方法不仅不能 有效的处理各类异常,同时使得整个系统流程复杂化;而完全的人工参与也使得异常处理过 程效率低下,形式极不规范。所以,工作...
第7章 java异常处理
SQLserver存储过程异常处理
这是自己通过看书对java异常处理的一些总结
高效的java异常处理框架高效的java异常处理框架高效的java异常处理框架高效的java异常处理框架高效的java异常处理框架