SizeLimitExceededException, FileSizeLimitExceededException, MaxUploadSizeExceededException 등 MultipartException 발생 시
핸들러 구현 및 필요한 추가 설정 (클라이언트에서 Response 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