[MultipartException] ExceptionHandler 구현 후, jqXHR.responseText 를 통해 응답 바디 접근 시 undefined 출력되는 경우

TenaLee·2021년 5월 6일
0

SizeLimitExceededException, FileSizeLimitExceededException, MaxUploadSizeExceededException 등 MultipartException 발생 시
핸들러 구현 및 필요한 추가 설정 (클라이언트에서 Response Body 접근 시, undefined 발생하지 않도록 필요한 설정)

상황

  1. SizeLimitExceededException, 익셉션 핸들러 구현 시 에러 정보 응답 Body에 담아 클라이언트에 리턴
  2. Ajax 파일 업로드 시 위의 익셉션이 터졌을 경우, 클라이언트 에러 콜백에서 응답 Body에 셋팅된 메시지 출력
  3. 그러나 클라이언트에서 응답 Body 접근 시 undefined 발생

문제

서버 측에서 SizeLimitExceededException 핸들링 후 Error 정보를 응답 바디에 담아줘도 클라이언트에서 접근시 undefined 가 발생

  • 비동기 요청 시 요청 Body의 최대 크기 초과 시 서블릿 컨테이너인 Tomcat 레벨에서 SizeLimitExceededException 발생한다.

  • 최종적으로 이 예외를 스프링에서 MultipartException 의 하위 타입인 MaxUploadSizeExceededException 으로 뱉는다.

  • 해당 익셉션을 뱉은 곳이 특정 컨트롤러가 아닌 애플리케이션 레벨에서 터진 익셉션이기 때문에 간단히 @ControllerAdvice + @ExceptionHandler 방식의 처리를 구현하면 끝일 줄 알았다.

  • 글로벌 익셉션 핸들러를 통해 해당 익셉션을 catch 할 수는 있다.
    그러나 문제는 서버측에서 핸들러 처리 후 내린 응답 Body가 클라이언트 측에 전달되지 않는다.

  • 따라서 익셉션 핸들러를 구현해놨지만, 결과적으로 예외를 완벽히 핸들링 할 수 없는 것과 다름 없고, 그 이유를 풀자면 다음과 같다.

    1) 서버 쪽에서 해당 익셉션 핸들링 후, 클라이언트 응답 Body에 Error 정보를 담아 내려준다

    2) 클라이언트 측에서 jqXHR.responseText 를 통해 응답 Body 접근 시 undefined 가 출력되고, 서버 쪽에서 핸들러 처리 후 리턴한 데이터를 받을 수 없다.

    3) 따라서 서버 쪽 응답 결과를 토대로 어떤 메시지 출력이나 다른 처리를 할 수 없게 된다.

    (테스트 삼아 한번에 삼키는 요청 바디의 크기를 1MB까지 극단적으로 설정하고 테스트 해보면, 단일 파일 업로드일 경우 익셉션이 터졌을 때 핸들러에서 처리한 응답 바디가 클라이언트로 잘 전달되지만, 다수의 파일 업로드 시 파일 각각에서 연달아 익셉션이 터지는 경우는 아니했다.)

결론

해당 이슈를 해결하기 위한 결론을 요약하면 다음과 같다.

application.yml (or properties) 에 다음 설정을 추가한다.

# application.yml
server:
  tomcat:
    max-swallow-size: -1
    
# application.properties
server.tomcat.max-swallow-size = -1
  • 핵심 설정 : server.tomcat.max-swallow-size = -1
  • 비동기 ajax 요청 시 수용할 수 있는 요청 Body의 최대 크기를 -1 로 설정 후, 사용자 정의 예외처리 구현를 구현한다.
profile
Tenacity

0개의 댓글