异常抛出与捕获的思考

Posted hlx-001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异常抛出与捕获的思考相关的知识,希望对你有一定的参考价值。

异常处理的思考

 

在java中异常分为两类。一、检查性异常。二、非检查性异常(运行时异常)

 

技术分享图片

 

二者的区别:检查性异常需要显式try-catch或者throw。运行时异常可以不用捕获。

对于检查性异常由于必须捕获,所有并不需要太多的讨论(在设计异常的时候需要考虑)。主要讨论运行时异常的抛出与捕获。

运行时异常的正确捕获和抛出,能够让系统代码更加简洁与rd只需要关系正常业务,对于不正常业务则交由异常处理。

 

现在存在的困扰:

1、每调用一个其他方法,都需要考虑与分析这个方法是不是存在异常,影响正常业务流程。

2、在业务调用链中,每个方法都存在try-catch块,代码结构沉余,不利于维护,每个方法都捕获与打印异常,造成日志或者错误信息重复,不利于精确定位问题。

3、在业务方法调用链中,一个业务的结果对象会作为方法的返回值,在调用连中层层传递,并需要构造正常结果与异常结果。返回值有时候并不能快速或者正确得终止异常流程,需要很多的return语句块。

 

在java web结构中整体的一个设想的是:

技术分享图片

 

1、在基础方法(非业务方法)中进行异常的捕获与异常的抛出,基础方法处于调用链底端主要在dao、util、daomian、service层中,基础方法基本不与业务或者流程相关,职责相对单一并存在异常风险。

     数据库操作:例子:1、查询一个车商;2、保存一个退款...。可能存在的异常或者错误:数据库连接超时;连接数过多,索引主键冲突...;

     rpc远程调用第三方接口:例子:1、获取财务保证金接口、2、根据carId获取车源信息。可能存在的异常或者错误:连接超时,返回结果参数不匹配...。

     文件IO操作:

     对基础方法进行异常捕获,打印错误堆栈信息(log),抛出异常(运行时异常,便于调用方理解,而不是堆栈信息)进行业务结束。即log输出异常堆栈信息,给rd使用,抛出异常进行业务结束与输出前端或者调用方可理解信息。

     基础方法相当于地基,地基必须是稳固的,完备的。

 

2、在controller、service与domain层进行业务逻辑开发,业务逻辑开发只专注正常流程,调用基础方法,不捕获异常。出现业务异常进行异常抛出,抛出可理解的异常信息与log输出详细堆栈错误信息。

     1、不进行异常捕获,调用的是基础方法或者其他业务,在基础方法已经进行了捕获与转换。所以不需要进行异常捕获。除非某些异常不影响业务或者需要做异常捕获和抛出(比如,新建退款单的时候会给bd发送一条通知告诉bd,然后bd去登陆处理。发送通知失败并不会影响业务流程,可以吃掉异常或者捕获处理)。

     2、在业务方法中出现异常的原因主要有两种:1、传参与调用其他方法返回值异常。2、业务异常(退保的时候,用户保证金不足1000)。出现这些情况,直接进行异常抛出,终止业务继续执行,而不是通过返回值进行返回。至于调用的方法出现异常则不捕获,因为调用的方法主要是业务方法与基础方法(基础方法已经经过处理),直接由高层捕获。

    业务方法相当于房子的内部空间,默认地基是牢固的,外墙是隔绝的,怎么构造是自己的事,外部无权关系,所以放开专注于业务逻辑。

 

3、全局异常捕获,捕获业务层抛出或者未捕获的异常进行统一处理,显示给前端,而不是让前端看到一个500的内部错误。

     外部全局捕获相当于房子的外墙,给外部看到的都是正确与经过处理的,看不到内部的瑕疵。

 

4、自定义异常可以考虑分为DaoException、DomainException、ServiceException,便于区分与定位异常。

 

5、在spring boot中使用ControllerAdvice处理全局异。对于Filter中的异常,在aop之前执行,使其跳转到ExceptionController中处理

 

需要注意的地方:

1、业务方法进行参数校验与调用其他方法的参数校验,校验失败抛出异常。

2、业务抛出的异常说明必须通俗易懂,log则要具体详细。

3、方法必须完备,除抛出异常或者调用其他方法出现异常外,不应该存在自己未知的异常(即自己不能在该方法体中构造而非抛出异常),简而言之,就是不能写出可能存在异常的代码(比如空指针异常)。

4、异常不能吃掉而不做处理,catch方法体内容为空。

5、不要在循环中抛出异常。

6、尽量在高层次捕获异常。

 

     

 

 

以上是关于异常抛出与捕获的思考的主要内容,如果未能解决你的问题,请参考以下文章

一文读懂 JAVA 异常处理

一文读懂 JAVA 异常处理

为啥java中Exception的对象能够获取子类的信息.

Java语言程序设计 上机实验5 异常

4.异常捕获后再次抛出

Java中的异常的捕获和抛出是啥意思,有啥区别