인프런 커뮤니티 질문&답변

liltjay님의 프로필 이미지

작성한 질문수

스프링 MVC 2편 - 백엔드 웹 개발 활용 기술

예외 처리에 대해 질문 있습니다.

해결된 질문

작성

·

143

·

수정됨

0

아래 내용은 제가 정리한 글입니다.


 

- 예외 처리 흐름

🧸 Spring MVC 내부에서 예외 처리:

1. 예외 발생: 컨트롤러에서 예외가 발생한다.

2. 예외 전파: 예외가 DispatcherServlet으로 전파된다.

3. HandlerExceptionResolver: DispatcherServlet은 등록된 예외 처리기를 통해 예외를 처리하려고 시도한다.

4. Custom Exception Handlers: @ControllerAdvice에 정의된 예외 처리기가 있으면 이를 사용하여 예외를 처리한다.

5. BasicErrorController: 위의 처리기들에서 예외를 처리하지 못하면, /error 경로로 요청이 전달되어 BasicErrorController가 기본적인 에러 처리를 수행한다.

6. 클라이언트 응답: BasicErrorController가 예외를 처리하고 클라이언트에게 적절한 에러 응답을 반환한다.

🧸 WAS로 예외 전파:

1. 예외 처리 실패: DispatcherServlet이나 BasicErrorController가 예외를 처리하지 못한다.

2. WAS로 전파: 예외가 WAS(톰캣)로 전파된다.

3. 에러 설정에 따른 재요청: WAS는 Spring Boot가 설정한 에러 핸들링 설정에 따라 /error 경로로 재요청을 보낸다.

4. 에러 처리: /error 경로로 재요청된 에러를 BasicErrorController가 처리한다.

5. 클라이언트 응답: BasicErrorController가 예외를 처리하고 클라이언트에게 적절한 에러 응답을 반환한다.

위의 흐름에서 알 수 있듯이, 기본적인 에러 처리 방식은 컨트롤러에서 발생한 예외를 BasicErrorController를 통해 처리하는 것이다. 예외가 WAS까지 전파되는 경우는 예외적인 상황이며, 일반적으로는 Spring MVC 내부에서 예외가 처리된다.


 

간단하게 얘기해서 예외 또는 에러가 WAS까지 전파되는 상황은 드물고, 주로 Spring MVC(ControllerAdvice, RestControllerAdvice, ExceptionHandler, ResponseStatus, ResponseStatusException, BasicErrorController)가 처리하여 컨트롤러단에서 예외가 처리되는 것으로 이해를 하고 정리를 하였습니다.

 

그런데 검색을 하다보니 아래와 같은 내용들을 발견하였습니다.


  1. Spring은 BasicErrorController를 구현해두었다.

    ExceptionHandler나 ControllerAdvice처럼 직접 에러를 반환하는 경우에는 BasicErrorController를 거치지 않지만,

    @ResponseStatus, ResponseStatusException 등과 같이 직접 에러 응답을 반환하지 않는 경우에는 최종적으로 BasicErrorController를 거쳐 에러가 처리된다.

    클라이언트 입장에서는 이를 모르지만 내부에서는 2번 컨트롤러로 요청이 전달되는 과정이 진행된다.

  2. 우리가 만든 예외 클래스에 다음과 같이 @ResponseStatus로 응답 상태를 지정해줄 수 있다.


@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class NoSuchElementFoundException extends RuntimeException {
  ...
}
 
 
// 그러면 ResponseStatusExceptionResolver가 지정해준 상태로 에러 응답이 내려가도록 처리한다.

{
    "timestamp": "2021-12-31T03:35:44.675+00:00",
    "status": 404,
    "error": "Not Found",
    "path": "/product/5000"
}

하지만 에러 응답에서 볼 수 있듯이 이는 BasicErrorController에 의한 응답이다. 즉, @ResponseStatus를 처리하는 ResponseStatusExceptionResolver는 WAS까지 예외를 전달시키며, 복잡한 WAS의 에러 요청 전달이 진행되는 것이다. (WAS까지 예외가 전달되고, WAS의 에러 요청 전달이 진행됨)


그렇다면 제가 정리한 내용과 위 내용은 반대되는데, 어떤 것이 맞는건지 잘 모르겠습니다.
제가 정리한 내용이 맞다면, @Responsestatus는 ExceptioNResolver, 정확하게는 ResponseStatusExceptionResolver에 의해서 처리되므로 컨트롤러단에서 예외처리가 되어야 하는것이 맞다고 생각하는데, 어떤 것이 참인가요?

 

답변 1

0

안녕하세요, 인프런 AI 인턴입니다.

님의 질문에 대한 답변은 Spring MVC 내에서 처리되는 예외와 관련된 정보입니다.

Spring Boot는 /error 매핑을 통해 모든 오류를 합리적인 방식으로 처리하는 기능을 기본적으로 제공합니다. 예외가 @ResponseStatusResponseStatusException 등을 통해 발생할 경우, 기본적으로 BasicErrorController를 거쳐 처리됩니다. 이 과정은 클라이언트 입장에서 불투명할 수 있으나, Spring Framework 내부에서는 예외가 BasicErrorController로 전달되어 처리되는 과정이 이루어집니다.

@ResponseStatusResponseStatusException이 적용된 예외는 ResponseStatusExceptionResolver에 의해서 처리되며, 이때 설정된 HTTP 상태 코드에 따라 응답이 이루어집니다. 그리고 이러한 처리는 Spring MVC 내에서 완결되기 때문에, 대부분의 경우 WAS까지 예외가 전파되지 않습니다. 예외가 WAS까지 전달되어 처리되는 경우는 일반적으로 예외 처리 과정에서 누락이나 오류가 발생했을 때로, Spring 내부에서 예외 처리가 적절히 이루어진다면 이러한 상황은 드물게 발생합니다.

따라서 님의 이해하신 바와 같이, Spring MVC 내에서 ControllerAdvice, ExceptionHandler 등을 통해 예외 처리가 이루어지고, 특정 예외 상황에 대해서는 @ResponseStatusResponseStatusException을 통해 HTTP 응답 상태를 직접 제어할 수 있으며, 이 과정에서 BasicErrorController가 최종적인 에러 처리를 담당하는 것으로 이해하시면 됩니다.

정리하자면, 님의 정리한 내용이 맞으며, @ResponseStatus 및 관련 예외 처리 메커니즘은 Spring MVC 내에서 예외를 처리하는 과정의 일부로 볼 수 있습니다.

liltjay님의 프로필 이미지

작성한 질문수

질문하기