-1

I use a global exception handler built by @ControllerAdvice as shown below and I catch custom exception e.g. NoSuchElementFoundException without any problem. If there is any uncaught error, then handleAllUncaughtException catches them.

On the other hand, I created 2 other custom exception classes to catch MaxUploadSizeExceededException and FileSizeLimitExceededException. But I cannot catch the error by these methods and catch by handleAllUncaughtException.

Here is the error details:

Exception details

@RestControllerAdvice
public class DefaultExceptionHandler extends ResponseEntityExceptionHandler {    

    // for NoSuchElementFoundException
    @ExceptionHandler(NoSuchElementFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ResponseEntity<Object> handleNoSuchElementFoundException(NoSuchElementFoundException ex, 
                                  WebRequest request) {
        log.error(FAILED_TO_FIND_ELEMENT, ex);
        return buildErrorResponse(ex, HttpStatus.NOT_FOUND, request);
    }


    // I am trying to catch the custom exception using one of these methods:
    // MaxUploadSizeExceededException and FileSizeLimitExceededException
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    @ResponseStatus(HttpStatus.PAYLOAD_TOO_LARGE)
    public ResponseEntity<Object> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException ex, 
                                     WebRequest request) {
        return buildErrorResponse(ex, HttpStatus.PAYLOAD_TOO_LARGE, request);
    }

    @ExceptionHandler(FileSizeLimitExceededException.class)
    @ResponseStatus(HttpStatus.PAYLOAD_TOO_LARGE)
    public ResponseEntity<Object> handleFileSizeLimitExceededException(FileSizeLimitExceededException ex, 
                                     WebRequest request) {
        return buildErrorResponse(ex, HttpStatus.PAYLOAD_TOO_LARGE, request);
    }


    // for all Uncaught Exceptions
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<Object> handleAllUncaughtException(Exception ex, 
                                                             WebRequest request) {
        return buildErrorResponse(ex, UNKNOWN_ERROR, HttpStatus.INTERNAL_SERVER_ERROR, request);
    }

    // code omitted
}

My custom exception classes are similar to NoSuchElementFoundException, and there is nothing wrong related to these classes. Here is one of them:

public class MaxUploadSizeExceededException extends RuntimeException {

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

1. So, which exception type (MaxUploadSizeExceededException or FileSizeLimitExceededException) should I use for creating custom class and how to catch catch this error in my custom method?

2. Is the HTTP status code (PAYLOAD_TOO_LARGE) correct?

Update: Here is stack trace:

org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException: the request was rejected because its size (3221) exceeds the configured maximum (1024)
    at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.handleParseFailure(StandardMultipartHttpServletRequest.java:122) ~[spring-web-5.3.21.jar:5.3.21]
    at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:115) ~[spring-web-5.3.21.jar:5.3.21]
    at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.<init>(StandardMultipartHttpServletRequest.java:88) ~[spring-web-5.3.21.jar:5.3.21]
    at org.springframework.web.multipart.support.StandardServletMultipartResolver.resolveMultipart(StandardServletMultipartResolver.java:122) ~[spring-web-5.3.21.jar:5.3.21]
    at org.springframework.web.servlet.DispatcherServlet.checkMultipart(DispatcherServlet.java:1205) ~[spring-webmvc-5.3.21.jar:5.3.21]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039) ~[spring-webmvc-5.3.21.jar:5.3.21]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.21.jar:5.3.21]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.21.jar:5.3.21]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.21.jar:5.3.21]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) ~[tomcat-embed-core-9.0.64.jar:4.0.FR]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.21.jar:5.3.21]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.64.jar:4.0.FR]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.64.jar:9.0.64]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.21.jar:5.3.21]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.21.jar:5.3.21]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.21.jar:5.3.21]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1787) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException: the request was rejected because its size (3221) exceeds the configured maximum (1024)
    at org.apache.catalina.connector.Request.parseParts(Request.java:2974) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.catalina.connector.Request.getParts(Request.java:2834) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.catalina.connector.RequestFacade.getParts(RequestFacade.java:1098) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:95) ~[spring-web-5.3.21.jar:5.3.21]
    ... 43 common frames omitted
Caused by: org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException: the request was rejected because its size (3221) exceeds the configured maximum (1024)
    at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.init(FileItemIteratorImpl.java:161) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.getMultiPartStream(FileItemIteratorImpl.java:205) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.findNextItem(FileItemIteratorImpl.java:224) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.<init>(FileItemIteratorImpl.java:142) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.tomcat.util.http.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:252) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.tomcat.util.http.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:276) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    at org.apache.catalina.connector.Request.parseParts(Request.java:2932) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
    ... 46 common frames omitted
Rishal
  • 1,480
  • 1
  • 11
  • 19
  • `spring.servlet.multipart.max-file-size=10MB spring.servlet.multipart.max-request-size=10MB server.tomcat.max-swallow-size=-1 //for embedded tomcat` you have added these properties in your application.properties? – Rishal Jul 31 '22 at 09:35
  • yeah, but for test purpose I set them to 1KB. Here are the properties in my `application.properties` file: `spring.servlet.multipart.max-file-size=1KB` , `spring.servlet.multipart.max-request-size=1KB`. But still catched via `handleAllUncaughtException` method. Any idea? –  Jul 31 '22 at 09:39
  • Include stacktrace and the above details in the question. – Rishal Jul 31 '22 at 09:42
  • I check via `ex.stackTrace` and `ex.getStacckTrace()` on Intellij watch section, but it includess too many element as list. So, which part do you mean? Or how should I get it to give details briefly? –  Jul 31 '22 at 09:45
  • you should log the traces and share it here. – Rishal Jul 31 '22 at 09:49
  • So you mean `System.out.println(ex.getStackTrace());` –  Jul 31 '22 at 09:52
  • May it be related to that `java.lang.IllegalStateException` comes before `org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException` in the stack trace? –  Jul 31 '22 at 09:56
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/246927/discussion-between-rishal-and-hans). – Rishal Jul 31 '22 at 10:16

1 Answers1

1

Your custom exception classes are not getting called anywhere, If you have declared any custom exception class and you want it to be handled accordingly you need to throw them as per below example.

Custom Exception Class

public class CustomMaxUploadSizeExceededException extends RuntimeException {
    public CustomMaxUploadSizeExceededException (String message) {
        super(message);
    }
}

Service Class

class FileuploadServiceImpl {
    public UploadResponse uploadFile() {

        //do some validation on file size
        if (validate) {
            //process normally
        } else {
            throw MaxUploadSizeExceededException("File size exceeded the permitted limit");
        }
        

    }
}

ExceptionHandlerAdvice

@RestControllerAdvice
@Slf4j
public class CustomExceptionHandler {
    @ExceptionHandler(CustomMaxUploadSizeExceededException.class)
    @ResponseStatus(HttpStatus.PAYLOAD_TOO_LARGE)
    public ResponseEntity<Object> handleMaxUploadSizeExceededException(CustomMaxUploadSizeExceededException ex, WebRequest request) {
        log.error(ex.getMessage(), ex);
        return buildErrorResponse(ex, ex.getMessage(), request);
    }
}

Another approach would be to just try to add method resolving to exception thrown as per your stacktrace which is MaxUploadSizeExceededException as below

@ExceptionHandler(MaxUploadSizeExceededException.class)
@ResponseStatus(HttpStatus.PAYLOAD_TOO_LARGE)
public ResponseEntity<Object> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException ex, WebRequest request) {
    log.error(ex.getMessage(), ex);
    return buildErrorResponse(ex, ex.getMessage(), request);
}
Rishal
  • 1,480
  • 1
  • 11
  • 19