Back-End/Spring Boot

예외처리

newny 2023. 8. 25. 01:27
반응형

서블릿 밖으로 까지 예외가 전달되는 경우 서블릿의 예외 처리 방식

@GetMapping("/error-ex")
public void errorEx() {
    throw new RuntimeException("예외 발생");
}

@GetMappint("/error-500")
public void error500(HttpServletResponse response) throw IOException {
	response.sendError(500);
}

'Exception'의 경우서버 내부에서 처리할 수 없는 오류가 발생한 것으로 생각해서 HTTP 상태 코드 500을 반환한다.

 

서블릿의 예외처리 2가지 방식

  • Exception (예외)
  • reponse.sendError (HTTP 상태코드, 오류메세지)

 

ExceptionResolver 활용

public class MyHandlerExceptionResolver implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {

        try {
            if (ex instanceof IllegalArgumentException) {
                log.info("IllegalArgumentException resolver to 400");
                response.sendError(HttpServletResponse.SC_BAD_REQUEST, ex.getMessage()); // 500예외를 400예외로 바꿔줌
                return new ModelAndView(); //빈값 반환 -> 뷰를 렌더링 하지 않고 정상 흐름으로 서블릿이 리턴됨
            }
        } catch (IOException e) {
            log.error("resolver ex", e);
        }
        return null;
        // null을 반환하면 다음 ExceptionResolver를 찾아서 실행함, 만약 처리할 수 있는 ExceptionResolver가 없다면
        // 예외처리가 안되고, 기존에 발생한 예외를 서블릿 밖으로 던짐
    }
}
  • ExceptionResolver를 등록할 때 configureHandlerExceptioResolver() 를 사용하면 스프링이 기본으로 등록하는 ExceptionResolver가 제거되므로 주의해야함 → 따라서 extendHandlerExceptionResolver() 를 사용해야함
  • 서블릿 컨테이너까지 예외가 올라가면 복잡하고 지정분하게 추가 프로세스가 실행된다. 반면에 ExceptionResolver를 사용하면 예외처리가 상당히 깔끔해 진다.

 

ResponseStatusExceptionResolver

@ResponseStatus

예외에 위의 어노테이션을 적용하면 HTTP 상태 코드를 변경해준다

@ResponseStatus(code = HttpStatus.BAD_REQUEST, reason = "error.bad")
public class BadRequestException extends RuntimeException {}

 

DefaultHandlerExceptionResolver

스프링 내부 예외 처리

 

ExceptionHandlerExcetpionResolver

@ExceptionHandler

  • 서블릿 컨테이너를 다시 왔다갔다 할 필요 없이, exception 처리를 한 후 정상 로직으로 반환해줌
  • 해당 어노테이션을 사용한 메소드를 포함하는 컨트롤러 전체에서 사용됨
  • 따라서 @ResponseStatus 어노테이션으로 상태코드를 변경하지 않으면 정상 로직으로 반환되기 때문에 결과가 200으로 뜸
  • 메소드 파라미터가 스프링 컨트롤러의 파라미터처럼 다양함 (리턴타입도 마찬가지)
반응형