如何优雅的处理接口返回值异常? [学习核心包系列三]
项目的核心代码都封装在核心包中. 本系列文章记录笔者阅读源码的过程和相应的实践.
一个问题
当接口传入的数据检查无异常时, 程序将往数据库写数据, 如果写入异常. 当前接口没有做任何处理, 直接把错误返给调用方.
似乎, 这样不妥当的.
1 2 3 4 5
| 需求:
程序应该记录下数据库原始错误. 并返给调用方一个温柔的响应.
那么, 如何实现?
|
解决问题
- 首先在Dao层增加异常捕获, 看看能否打印出来.
1 2 3 4 5
| try { insert = insert(sql); } catch (Exception e) { throw new YxException(e.getMessage()); }
|
- 增加一个自定义异常. 在Dao层抛出该异常.
1 2 3 4 5
| public class YxDBException extends YXException { public YxDBException(String message) { super(message); }
|
- 利用 ControllerAdvice. 批量处理该异常.
1 2 3 4 5 6 7 8 9 10 11
| @Slf4j @ControllerAdvice public class ExceptionController {
@ExceptionHandler(YxDBException.class) @ResponseBody public Result IncorrectCredentialsException(YxDBException e) { log.error(e.getMessage(), e.getException()); return ResultGenerator.genFailMessage("数据库写入失败, 请检查数据合法性"); }
|
按目前的方式, 在每一个方法上都增加捕获异常就可以解决问题. 可以但没有必要.
如果代码结构合理. 那么执行SQL的方法都应该在DAO层. 那么通过AOP拦截该层即可.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| @Slf4j @Component @Aspect public class DaoAspect {
@Around("execution(* com.yxkj.jk.yibao.dao.*.*(..))") public Object aspectDaoExcpet(ProceedingJoinPoint pjp) { Object obj;
try { obj = pjp.proceed(); } catch (Throwable e) { throw new YxDBException(e.getMessage()); }
return obj; } }
|