我们的技术栈是 spring+mybatis+mysql,一共分为 4 层 请求-->rest-->manager-->领域(业务)-->service(增删改查服务)--->mapper--数据库 对于异常处理讨论出了非常奇怪的结果,比如一个情景,如果 mapper 访问数据库出现了异常,service 层拿到这个异常,记录错误日志,再包装成 service 层的异常抛向上一层,到了领域层,它重复 service 的任务(记录错误日志,再包装成领域的异常,再把新的异常抛向上一层),rest 层返回手动在 rest 层定义的错误代码给前端。一个错误被包装了好几次,生成多条错误日志,这样做的理论依据是什么呢?
1
Athrob 2018-06-15 23:11:30 +08:00
感觉这样挺合适的, 不用去关心其他层怎样处理, 自己这层有异常了处理好再往上抛就行.
|
2
neoblackcap 2018-06-15 23:21:29 +08:00
异常不都这样吗?能处理就处理,不能处理就中断,挂掉防止进一步出错吗?
|
3
gzq527 2018-06-15 23:22:33 +08:00
spring mvc 有统一异常处理机制。
|
4
gzq527 2018-06-15 23:24:02 +08:00
在 rest 层捕获异常,其它层都往上抛
|
5
serical 2018-06-16 02:03:35 +08:00 via Android
统一异常处理 RestControllerAdvice
|
6
lrh3321 2018-06-16 06:46:20 +08:00 via Android
统一处理异常,ControllerAdvice。service 碰到不知道怎么处理的异常,就根据业务 /异常类型封装成自己定义的异常,直接往上抛。
|
7
loongwang 2018-06-16 09:30:16 +08:00
统一异常处理+1.
自定义错误码,实现 HandlerExceptionResolver 如果是自定义异常,从资源文件解析错误码对应的错误信息。 如果非自定义,log+默认错误码。 前端也需要一套捕捉机制 |
8
loongwang 2018-06-16 09:31:30 +08:00 1
贴一下我司的实现
@Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) { BusinessException exception; ErrorRes errorRes; if (e instanceof BusinessException) { exception = (BusinessException) e; errorRes = new ErrorRes("" + exception.getErrorCode(), exception.getMessage(), exception.getErrorParameters()); logger.warn( errMsgLogid + String.format( "warn code:%s, errorMessage:%s, errorParameters:%s", exception.getErrorCode(), exception.getMessage(), exception.getErrorParameters()), e); } else { exception = new BusinessException(ErrorCode.SYSTEM_ERROR, e); errorRes = new ErrorRes("" + exception.getErrorCode(), exception.getMessage()); // 获取异常名称 String exceptionName = e.getClass().getName(); if ("org.apache.catalina.connector.ClientAbortException" .equalsIgnoreCase(exceptionName)) { logger.warn(errMsgLogid + "system warn:", e); } else if ("javax.ws.rs.ClientErrorException" .equalsIgnoreCase(exceptionName)) { logger.warn(errMsgLogid + "system warn:", e); } else { logger.error(errMsgLogid + "system error:", e); } } PrintWriter responseWriter = null; try { response.setContentType("application/json;"); response.setCharacterEncoding("UTF-8"); response.setStatus(Response.SC_OK); responseWriter = response.getWriter(); responseWriter.write(JSON.toJSONString(errorRes)); responseWriter.flush(); } catch (IOException e1) { logger.error(errMsgLogid, e1); } finally { if (responseWriter != null) { responseWriter.close(); } } return new ModelAndView(); } |
9
swim2sun 2018-06-17 14:34:34 +08:00
出现数据库这种异常,一层一层捕获再往上抛是不妥的,直接抛个运行时异常,再使用 Spring MVC 的全局异常处理就行了。太多处理异常的代码会导致代码可维护性和可读性都大打折扣
|
10
victorwu34 OP @Athrob 实际是系统中每一层都不处理异常,而是把异常的 stacktrack+自己写的上下文放进一个自定义的,继承与 runtime exception 的异常中,直到 rest 层再把自定义异常中的信息取出来,返回给前端的 json 中(异常实际上处理方式都是返回前端)。你不觉得这些异常包装都是空架子吗,最多提供了点儿上下文
|
11
victorwu34 OP @gzq527 我们没用 mvc,这样不是多加了依赖吗
|
12
victorwu34 OP @loongwang 很复杂,还没看明白
|
13
loongwang 2018-06-22 10:28:46 +08:00
|