异常抛出与捕获的思考

异常处理的思考

一、异常简介

在java中异常分为两类。一、检查性异常。二、非检查性异常(运行时异常),二者的区别:检查性异常需要显式try-catch或者throw。运行时异常可以不用捕获。对于检查性异常由于必须捕获,所有并不需要太多的讨论(在设计异常的时候需要考虑)。主要讨论运行时异常的抛出与捕获。运行时异常的正确捕获和抛出,能够让系统代码更加简洁与rd只需要关系正常业务,对于不正常业务则交由异常处理。

二、现在存在的困扰

  1. 每调用一个其他方法,都需要考虑与分析这个方法是不是存在异常,影响正常业务流程。
  2. 在业务调用链中,每个方法都存在try-catch块,代码结构沉余,不利于维护,每个方法都捕获与打印异常,造成日志或者错误信息重复,不利于精确定位问题。
  3. 在业务方法调用链中,一个业务的结果对象会作为方法的返回值,在调用连中层层传递,并需要构造正常结果与异常结果。返回值有时候并不能快速或者正确得终止异常流程,需要很多的return语句块。

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

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

数据库操作:例子:1、查询一个车商;2、保存一个退款…。可能存在的异常或者错误:数据库连接超时;连接数过多,索引主键冲突。rpc远程调用第三方接口。文件IO操作。
对基础方法进行异常捕获,打印错误堆栈信息(log),抛出异常(运行时异常,便于调用方理解,而不是堆栈信息)进行业务结束。即log输出异常堆栈信息,给rd使用,抛出异常进行业务结束与输出前端或者调用方可理解信息。
基础方法相当于地基,地基必须是稳固的,完备的。

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

    2-1 不进行异常捕获,调用的是基础方法或者其他业务,在基础方法已经进行了捕获与转换。所以不需要进行异常捕获。除非某些异常不影响业务直接吃掉,或者显示捕获做逻辑处理。
    2-2 在业务方法中出现异常的原因主要有两种:1、参数校验异常。2、调用其他方法异常。3、业务异常。出现这些情况,直接进行异常抛出,终止业务继续执行,而不是通过返回值进行返回。至于调用的方法出现异常则不捕获,因为调用的方法主要是业务方法与基础方法(基础方法已经经过处理),直接由高层捕获。
    业务方法相当于房子的内部空间,默认地基是牢固的,外墙是隔绝的,怎么构造是自己的事,外部无权干预,所以放开专注于业务逻辑。

  2. 全局异常捕获,捕获业务层抛出或者未捕获的异常进行统一处理,显示给前端,而不是让前端看到一个500的内部错误。
  3. 自定义异常可以考虑分为CommonException、BusinessException、FatalException等,便于区分异常种类与优先级。
  4. 在spring boot中使用ControllerAdvice处理全局异常
结论:基础方法进行异常捕获处理,业务方法、业务流程不做异常捕获处理。
tips:

考虑的程序的完备性,在我们调用其他接口的时候,最好的话对接口的返回值都进行判空处理,已防止NPE。这样的 话很多时候其实没有必要,然后代码也显得杂乱,每个调用接口都有判空逻辑,然后方法间的层层调用,让很多时候显得没有必要。
考虑使用Optional,然后进行接口约定。对于直接返回普通的对像的接口默认都不进行空指针判断,可能返回空的接口一律Optional对像返回。

四、 需要注意的地方:

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

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

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

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

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

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

个人看法,欢迎大家指正。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值