朱晔《Java业务开发常见错误100例》课程学习整理
异常处理
不建议在框架层面进行异常的自动、统一处理,尤其不要随意捕获异常。但是异常上升到最上层逻辑还是无法处理,可以以统一的方式进行异常转换,比如@RestControllerAdvice + @ExceptionHandler,捕获未处理异常
(1)对于自定义业务异常,以Warn级别的日志记录异常以及当前URL、执行方法等信息,提取异常中的错误码和消息等信息,转换为合适的API包装体返回给API调用方;
(2)对于无法处理的系统异常,以Error级别的日志记录异常和上下文信息(比如URL、参数、用户ID)转换为普适的“服务器忙,请稍后再试”异常信息,同样以API包装体返回调用方
1、注意捕获和处理异常的最佳实践。(1)不应该用AOP对所有方法进行统一异常处理,异常要么不捕获不处理,要么根据不同的业务逻辑、不同的类型进行精细化、针对性处理。(2)处理异常应杜绝生吞,确保异常栈信息得到保留。(3)如果需要重新抛出异常,要使用有意义的异常类型和异常消息。
2、注意finally代码块中组员回收逻辑,确保finally代码块不出现异常,内部把异常处理完毕,避免finally的异常覆盖try中的异常,或者使用addSuppressed方法把finally中的异常附加到try中的异常上,确保注意长信息不丢失。使用AutoCloseable接口的资源,务必使用try-with-resources模式来使用资源,确保资源可以正确释放,确保异常可以正确处理。
3、统一定义收口所有的业务异常时,确保异常是new出来的,如果使用预先定义的static字段存放异常,可能会引起栈信息的错乱
4、确保正确处理线程池种任务的异常,如果任务通过execute提交,出现异常会导致线程退出,大量异常会导致线程重复创建引起线程问题,在使用过程中需要尽可能确保任务不出异常,同时设置默认未捕获异常处理程序兜底;如果任务通过submit提交,则应该通过拿到的Future调用其get方法来获得任务运行结果和可能出现的异常。