一、问题现象
- 前端请求后台接口,拿到了response body,但是response state是500!这就很懵了,明明数据已经有了,为什么还是500呢?这个现象是上了生产之后服务健康监测发现的,提示系统接口返回5xx。下面是问题截图
二、问题排查
- 首先根据健康监测日志拿到对应接口信息
- 本地服务模拟请求,发现确实有这个问题!!!😱
- 进行断点调试,看一下哪里抛的这个异常信息:发现是从过滤器中抛出来的,看了一圈发现没什么问题,异常正常抛出,但是接口状态就是500。
- 经过多轮查资料终于找到了问题所在!!!
三、解决问题
- 先说原理:在过滤器中直接抛出xxException,这个Exception可以是系统的也可以是你系统自己定义的异常,这时候异常被抛出了,没有被处理,导致容器对未处理的异常响应code为500!!
- 解决办法:首先当然是把会抛出异常的代码try起来,然后捕获异常,但是这样发现跟我想要的不一样,我需要直接把异常信息当作response 响应给前端,这样捕获起来了就没办法给前端返回了。
- 解决response响应:首先需要创建一个ExceptionController,这个controller用于接收过滤器中抛出来的异常,返回给前端。
@RestController
public class ExceptionController {
@RequestMapping("/error/exThrow")
public void rethrow(HttpServletRequest request) throws Exception {
throw ((Exception) request.getAttribute("filter.error"));
}
}
同时在过滤器中你的异常捕获要这样处理
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
chain.doFilter(request, response);
} catch (Exception e) {
// 异常捕获,发送到error controller
request.setAttribute("filter.error", e);
//将异常分发到/error/exThrow控制器
request.getRequestDispatcher("/error/exThrow").forward(request, response);
}
}
完美解决