Spring boot Web 開發 - Error Handler

October 27, 2021

從官方介紹內容來看錯誤處理內從大概是以下

  1. 默認規則

異常整體流程處理

  1. 執行目標方法,只要期間有錯誤都會被 JAVA 的 catch 語法給抓到,並將當前請求結束,其過程會進入 dispatchException
  2. 進入 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException)
  3. 當中 mv = processHandlerException,處理 handler 發生的異常,接著回傳 ModelAndView,過程會遍歷 handlerExceptionResolvers,看誰能處理,系統默認的解析起有以下

定制錯誤邏輯

@ControllerAdvice+@ExceptionHandler

@RestControllerAdvice
@Slf4j
public class ExceptionHandlerAdvice {

    @ExceptionHandler(Exception.class) // 捕獲的異常,執行這個類別下對應的動作
    public ResponseResult<Void> handleException(Exception e) {
        log.error(e.getMessage(), e);
        return new ResponseResult<Void>(ResponseCode.SERVICE_ERROR.getCode(), ResponseCode.SERVICE_ERROR.getMsg(), null);
    }

    @ExceptionHandler(RuntimeException.class)
    public ResponseResult<Void> handleRuntimeException(RuntimeException e) {
        log.error(e.getMessage(), e);
        return new ResponseResult<Void>(ResponseCode.SERVICE_ERROR.getCode(), ResponseCode.SERVICE_ERROR.getMsg(), null);
    }

    @ExceptionHandler(BaseException.class)
    public ResponseResult<Void> handleBaseException(BaseException e) {
        log.error(e.getMessage(), e);
        ResponseCode code = e.getCode();
        return new ResponseResult<Void>(code.getCode(), code.getMsg(), null);
    }

}

@ResponseStatus+自定義異常

@ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "User too many")
public UserTooManyException extends RuntimeException {
    public UserTooManyException() {

    }
    public UserTooManyException(String message) {
        super(message);
    }
}

@GetMapping("/user/all")
public something getUser() {
    throw new UserTooManyException();
    return something;
}

可參考文章

HandlerExceptionResolver 自定義

@Order(value = Ordered.HIGHEST_PRECEDENCE)
@Component // 放在容器中
public class CustomHandlerExceptionResolver implements HandlerExceptionResolver{
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
            Exception ex) {
        // TODO Auto-generated method stub
        try {
            response.sendError(510, "Error...");
        } catch (Exception e) {
            //TODO: handle exception
        }
        return new ModelAndView();
    }
}

透過 Oeder 的註解讓當前異常處理優先權為最高。