title: Spring ControllerAdvice not firing for some exceptions but others
body: <p>I have a springboot rest service that can be accessed through the <code>/test</code> endpoint. I have setup a error handling controller like so:</p>
  
  <pre><code>@ControllerAdvice
  public class AppErrorController extends ResponseEntityExceptionHandler {
  
      @ExceptionHandler(InvalidHeaderException.class)
      public ResponseEntity&lt;JsonNode&gt; handleHeaderError(InvalidHeaderException ex) {
          return ResponseEntity
                  .status(HttpStatus.NOT_ACCEPTABLE)
                  .body(generateResponseJson(ex));
      }
  
      @ExceptionHandler(InvalidRequestException.class)
      public ResponseEntity&lt;JsonNode&gt; handleRequestError(InvalidRequestException ex) {
          return ResponseEntity
                  .status(HttpStatus.NOT_ACCEPTABLE)
                  .body(generateResponseJson(ex));
      }
  
      @ExceptionHandler(ServiceResponseException.class)
      public ResponseEntity&lt;JsonNode&gt; handleServiceError(ServiceResponseException ex) {
          return ResponseEntity
                  .status(HttpStatus.INTERNAL_SERVER_ERROR)
                  .body(generateResponseJson(ex));
      }
  
      private JsonNode generateResponseJson(Exception ex) {
          return ResponseBuilder.newBuilder()
                  .withException(ex.getClass().getSimpleName())
                  .withDescription(ex.getMessage())
                  .withTimestamp(LocalDateTime.now())
                  .buildAsJson();
      }
  }
  </code></pre>
  
  <p>I've tested this out and this works perfectly fine. If I test the api with a bad input then it returns:</p>
  
  <pre><code>{
    "exception": "InvalidRequestException",
    "description": "A valid input value is needed that is non-empty or non-null.",
    "timestamp": "2016-03-28T11:35:39.765"
  }
  </code></pre>
  
  <p>And this is what the log looks like in correlation with the <code>AppErrorController</code> handling the exception:</p>
  
  <pre><code>11:35:39.706 [http-bio-8080-exec-3] DEBUG org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'Foo_Engine' processing POST request for [/test]
  11:35:39.706 [http-bio-8080-exec-3] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Looking up handler method for path /test
  11:35:39.707 [http-bio-8080-exec-3] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Returning handler method [public org.springframework.http.ResponseEntity&lt;com.fasterxml.jackson.databind.JsonNode&gt; controllers.FooController.getFoosForRest(controllers.model.Request,org.springframework.validation.BindingResult)]
  11:35:39.708 [http-bio-8080-exec-3] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor - Read [class controllers.model.Request] as "application/json" with [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@3086f443]
  11:35:39.709 [http-bio-8080-exec-3] DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Resolving exception from handler [public org.springframework.http.ResponseEntity&lt;com.fasterxml.jackson.databind.JsonNode&gt; controllers.FooController.getFoosForRest(controllers.model.Request,org.springframework.validation.BindingResult)]: controllers.exceptions.InvalidRequestException: A valid input value is needed that is non-empty or non-null.
  11:35:39.761 [http-bio-8080-exec-3] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'appErrorController'
  11:35:39.762 [http-bio-8080-exec-3] DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Invoking @ExceptionHandler method: public org.springframework.http.ResponseEntity&lt;com.fasterxml.jackson.databind.JsonNode&gt; controllers.AppErrorController.handleRequestError(controllers.exceptions.InvalidRequestException)
  11:35:39.815 [http-bio-8080-exec-3] DEBUG org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor - Written [{"resultCode":false,"exception":"InvalidRequestException","description":"A valid input value is needed that is non-empty or non-null.","timestamp":"2016-03-28T11:35:39.765"}] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@3086f443]
  11:35:39.816 [http-bio-8080-exec-3] DEBUG org.springframework.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'Foo_Engine': assuming HandlerAdapter completed request handling
  11:35:39.816 [http-bio-8080-exec-3] DEBUG org.springframework.web.servlet.DispatcherServlet - Successfully completed request
  </code></pre>
  
  <p>This works great when with the <code>InvalidHeaderException</code> and <code>InvalidRequestException</code> but for some reason it doesn't work for <code>ServiceResponseException</code>. The first exception gets thrown by a header interceptor, the second gets thrown by the controller sitting up top and the 3rd one gets thrown by the inner code. Here is where it gets thrown:</p>
  
  <pre><code>public class Foo {
      private final Cache&lt;String, List&lt;Foo&gt;&gt; fooCache;
  
      public Foo() {
          fooCache = CacheBuilder.newBuilder().build();
      }
  
      public List&lt;Foo&gt; getFoo() {
          List&lt;Foo&gt; foos = null;
          try {
              foos = fooCache.get(foo.getId(),
                      () -&gt; populateCacheWithFoo());
          } catch (ExecutionException e) {
              e.printStackTrace();
          }
          return foos;
      }
  
      public List&lt;Foo&gt; populateCacheWithFoo() {
          JsonNode response = null;
          try {
              response = operation.postForObject(/* resource url */,
                      /* build header body */,
                      JsonNode.class);
          } catch (Throwable t) {
              throw new ServiceResponseException("Error with backend service - getResourceA operation");
          }
  
          List&lt;Foo&gt; foos = response.get("Foos");
  
          fooCache.put(foo.get(1).getId(), foos);
          return foos;
      }
  }
  </code></pre>
  
  <p>For some reason, whenever I throw this exception it just doesn't get caught by the <code>AppErrorController</code> and instead I get this stack trace:</p>
  
  <pre><code>11:23:43.085 [http-bio-8080-exec-1] DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Resolving exception from handler [public org.springframework.http.ResponseEntity&lt;com.fasterxml.jackson.databind.JsonNode&gt; controllers.FooController.getFoosForRest(controllers.model.Request,org.springframework.validation.BindingResult)]: com.google.common.util.concurrent.UncheckedExecutionException: controllers.exceptions.ServiceResponseException: Error with backend service - getResourceA operation
  11:23:43.086 [http-bio-8080-exec-1] DEBUG org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver - Resolving exception from handler [public org.springframework.http.ResponseEntity&lt;com.fasterxml.jackson.databind.JsonNode&gt; controllers.FooController.getFoosForRest(controllers.model.Request,org.springframework.validation.BindingResult)]: com.google.common.util.concurrent.UncheckedExecutionException: controllers.exceptions.ServiceResponseException: Error with backend service - getResourceA operation
  11:23:43.086 [http-bio-8080-exec-1] DEBUG org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Resolving exception from handler [public org.springframework.http.ResponseEntity&lt;com.fasterxml.jackson.databind.JsonNode&gt; controllers.FooController.getFoosForRest(controllers.model.Request,org.springframework.validation.BindingResult)]: com.google.common.util.concurrent.UncheckedExecutionException: controllers.exceptions.ServiceResponseException: Error with backend service - getResourceA operation
  11:23:43.096 [http-bio-8080-exec-1] DEBUG org.springframework.web.servlet.DispatcherServlet - Could not complete request
  com.google.common.util.concurrent.UncheckedExecutionException: controllers.exceptions.ServiceResponseException: Error with backend service - getResourceA operation
      at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2207)
      at com.google.common.cache.LocalCache.get(LocalCache.java:3953)
      at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4790)
      at services.Foo.getFoo(IdentityClientImpl.java:73)
      at controllers.FooController.getFoosForRest(FooController.java:61)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:497)
      at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222)
      at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
      at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
      at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814)
      at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737)
      at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
      at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
      at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
      at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:969)
      at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:871)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
      at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:845)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
      at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
      at org.springframework.boot.context.web.ErrorPageFilter.doFilter(ErrorPageFilter.java:120)
      at org.springframework.boot.context.web.ErrorPageFilter.access$000(ErrorPageFilter.java:61)
      at org.springframework.boot.context.web.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:95)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.springframework.boot.context.web.ErrorPageFilter.doFilter(ErrorPageFilter.java:113)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
      at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:957)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
      at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
      at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620)
      at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:745)
  Caused by: controllers.exceptions.ServiceResponseException: Error with backend service - getResourceA operation
      at services.Foo.populateCacheWithFoo(Foo.java:99)
      at services.Foo.lambda$getFoo$0(Foo.java:74)
      at com.google.common.cache.LocalCache$LocalManualCache$1.load(LocalCache.java:4793)
      at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3542)
      at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2323)
      at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2286)
      at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2201)
      ... 56 common frames omitted
  </code></pre>
  
  <p>Any idea why the first 2 exceptions are getting caught by the <code>AppErrorController</code> but not the 3rd one? Is there some configuration I need to do in my java config files? Here's my mvc configuration file:</p>
  
  <pre><code>@Configuration
  @EnableWebMvc
  public class MvcConfiguration extends WebMvcConfigurerAdapter {
      @Autowired
      ServletContext servletContext;
  
      @Autowired
      HeaderInterceptor interceptor;
  
      @Override
      public void addInterceptors(InterceptorRegistry registry) {
          registry.addInterceptor(interceptor);
      }
  
      @Override
      public void configureDefaultServletHandling(
              DefaultServletHandlerConfigurer configurer) {
          configurer.enable();
      }
  
      @Bean
      public ViewResolver getJspViewResolver() {
          InternalResourceViewResolver resolver = new InternalResourceViewResolver();
          resolver.setPrefix("WEB-INF/jsp/views/");
          resolver.setSuffix(".jsp");
          resolver.setOrder(1);
          return resolver;
      }
  }
  </code></pre>