V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
victorwu34
V2EX  ›  Java

一个大型项目异常怎么处理才对

  •  
  •   victorwu34 · 2018-06-15 22:39:11 +08:00 · 4417 次点击
    这是一个创建于 2351 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我们的技术栈是 spring+mybatis+mysql,一共分为 4 层 请求-->rest-->manager-->领域(业务)-->service(增删改查服务)--->mapper--数据库 对于异常处理讨论出了非常奇怪的结果,比如一个情景,如果 mapper 访问数据库出现了异常,service 层拿到这个异常,记录错误日志,再包装成 service 层的异常抛向上一层,到了领域层,它重复 service 的任务(记录错误日志,再包装成领域的异常,再把新的异常抛向上一层),rest 层返回手动在 rest 层定义的错误代码给前端。一个错误被包装了好几次,生成多条错误日志,这样做的理论依据是什么呢?

    13 条回复    2018-06-22 10:28:46 +08:00
    Athrob
        1
    Athrob  
       2018-06-15 23:11:30 +08:00
    感觉这样挺合适的, 不用去关心其他层怎样处理, 自己这层有异常了处理好再往上抛就行.
    neoblackcap
        2
    neoblackcap  
       2018-06-15 23:21:29 +08:00
    异常不都这样吗?能处理就处理,不能处理就中断,挂掉防止进一步出错吗?
    gzq527
        3
    gzq527  
       2018-06-15 23:22:33 +08:00
    spring mvc 有统一异常处理机制。
    gzq527
        4
    gzq527  
       2018-06-15 23:24:02 +08:00
    在 rest 层捕获异常,其它层都往上抛
    serical
        5
    serical  
       2018-06-16 02:03:35 +08:00 via Android
    统一异常处理 RestControllerAdvice
    lrh3321
        6
    lrh3321  
       2018-06-16 06:46:20 +08:00 via Android
    统一处理异常,ControllerAdvice。service 碰到不知道怎么处理的异常,就根据业务 /异常类型封装成自己定义的异常,直接往上抛。
    loongwang
        7
    loongwang  
       2018-06-16 09:30:16 +08:00
    统一异常处理+1.
    自定义错误码,实现 HandlerExceptionResolver
    如果是自定义异常,从资源文件解析错误码对应的错误信息。
    如果非自定义,log+默认错误码。
    前端也需要一套捕捉机制
    loongwang
        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();
    }
    swim2sun
        9
    swim2sun  
       2018-06-17 14:34:34 +08:00
    出现数据库这种异常,一层一层捕获再往上抛是不妥的,直接抛个运行时异常,再使用 Spring MVC 的全局异常处理就行了。太多处理异常的代码会导致代码可维护性和可读性都大打折扣
    victorwu34
        10
    victorwu34  
    OP
       2018-06-20 10:30:20 +08:00
    @Athrob 实际是系统中每一层都不处理异常,而是把异常的 stacktrack+自己写的上下文放进一个自定义的,继承与 runtime exception 的异常中,直到 rest 层再把自定义异常中的信息取出来,返回给前端的 json 中(异常实际上处理方式都是返回前端)。你不觉得这些异常包装都是空架子吗,最多提供了点儿上下文
    victorwu34
        11
    victorwu34  
    OP
       2018-06-20 10:32:14 +08:00
    @gzq527 我们没用 mvc,这样不是多加了依赖吗
    victorwu34
        12
    victorwu34  
    OP
       2018-06-21 22:30:05 +08:00
    @loongwang 很复杂,还没看明白
    loongwang
        13
    loongwang  
       2018-06-22 10:28:46 +08:00
    @victorwu34

    @swim2sun 说的很正确,我上面贴的代码就是这个意思.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2799 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 13:11 · PVG 21:11 · LAX 05:11 · JFK 08:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.