2016-03-28 35 views
0

/test uç noktasından erişilebilen bir yaya bekleme servisi var. Bir hata denetleyicisini şu şekilde ayarlayabilirsiniz:Yay Denetleyicileri Bazı istisnalar için yanmıyor ancak diğerleri

Bunu test ettim ve bu gayet iyi çalışıyor.

{ 
    "exception": "InvalidRequestException", 
    "description": "A valid input value is needed that is non-empty or non-null.", 
    "timestamp": "2016-03-28T11:35:39.765" 
} 

Ve bu günlük AppErrorController istisna işleme ile korelasyon içinde neye benzediği: Ben kötü girişli api test ederseniz o zaman döndüğünde ile

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<com.fasterxml.jackson.databind.JsonNode> 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.springfr[email protected]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<com.fasterxml.jackson.databind.JsonNode> 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<com.fasterxml.jackson.databind.JsonNode> 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.springfr[email protected]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 

Bu harika çalışıyor InvalidHeaderException ve InvalidRequestException ancak bazı nedenlerle ServiceResponseException için çalışmaz. İlk istisna, bir üstbilgi engelleyicisi tarafından atılır, ikincisi kontrolörün tepesine oturunca atılır ve üçüncüsü iç kod tarafından atılır. Burada atılan nerede: Nedense

public class Foo { 
    private final Cache<String, List<Foo>> fooCache; 

    public Foo() { 
     fooCache = CacheBuilder.newBuilder().build(); 
    } 

    public List<Foo> getFoo() { 
     List<Foo> foos = null; 
     try { 
      foos = fooCache.get(foo.getId(), 
        () -> populateCacheWithFoo()); 
     } catch (ExecutionException e) { 
      e.printStackTrace(); 
     } 
     return foos; 
    } 

    public List<Foo> 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<Foo> foos = response.get("Foos"); 

     fooCache.put(foo.get(1).getId(), foos); 
     return foos; 
    } 
} 

, bu istisna her sadece AppErrorController tarafından yakalanmak değildir ve bunun yerine bu yığın izleme almak:

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<com.fasterxml.jackson.databind.JsonNode> 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<com.fasterxml.jackson.databind.JsonNode> 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<com.fasterxml.jackson.databind.JsonNode> 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 

konusunda fikrin İlk 2 istisnai neden AppErrorController tarafından yakalanmakta, ancak 3. sırada değil? Java yapılandırma dosyalarında yapmam gereken bazı yapılandırma var mı? İşte benim mvc yapılandırma dosyası var:

sorun guava içinde Callable önbellek durum yakalamak almak ve onları kapsüllü yeniden atmak olmasıdır gibi
@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; 
    } 
} 
+0

'' mi 'ExecutionException'''' '' bir alt sınıfını ServiceResponseException''' ? – maximede

+0

@maximede aslında hayır, 'RuntimeException' değerini uzatır. ExecutionException öğesini uzatmalı mı? Diğer 2 istisnası da "RuntimeException" dan – Richard

+0

nope'a kadar uzanıyor, sadece korkuyordum '' '' 'ServiceResponseException'''' '' '' '' 'kamuya açık liste getFoo''' yönteminde yakalanmış olabilirsiniz aslında – maximede

cevap

1

görünüyor: http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/Cache.html#get(K,%20java.util.concurrent.Callable)

Sen bir yakalama madde eklemek isteyebilirsiniz senin getFoo() yöntemini ve özgün istisnayı yeniden atmak. Böyle şey:

public List<Foo> getFoo() throws ServiceResponseException{ 
    List<Foo> foos = null; 
    try { 
     foos = fooCache.get(foo.getId(), 
       () -> populateCacheWithFoo()); 
    } catch (ExecutionException e) { 
     Throwables.propagateIfPossible(
     e.getCause(), ServiceResponseException.class); 
    } 
    return foos; 
} 

Ama .getCause() gerçek istisna olduğunu teyit etmek catch bir kesme noktası koymak istiyorum olabilecek veya bunun feryat bir seviye olmadığını


Yoksa bu yapabileceğini Eğer bir kontrol istisna için ServiceException değiştirmek istemiyorsanız:

public List<Foo> getFoo() throws ServiceResponseException{ 
    List<Foo> foos = null; 
    try { 
     foos = fooCache.get(foo.getId(), 
       () -> populateCacheWithFoo()); 
    } catch (ExecutionException e) { 
     e.printStackTrace(); 
    } catch (UncheckedExecutionException e) { 
     Throwables.propagateIfPossible(
     e.getCause(), ServiceResponseException.class); 
    } 
    return foos; 
} 
+0

benim hata yakaladım ve 'Exception com.google.common.util diyor ki bu yüzden bunu yapmak için nasıl bir fikrim yok. .eşzamanlı.UncheckedExecutionException zaten yakalandı ' – Richard

+0

Sadece Guava hakkında biraz daha fazla okumak, ve ben senin sorununun düzeltmek için en kolay yolu '' '' 'Exception''' genişleterek kontrol edilen bir istisna' '' 'ServiceResponseException'' yapmak olurdu düşünüyorum '' 'RuntimeException''' yerine ve kodunuzu uyarlanmış cevabım – maximede

+0

’a benzeterek uyarlayarak bunu 'Exception'unu genişletmek için değiştirdim ve şimdi bu hatayı alıyorum:' java: rapor edilmemiş istisna kontrolörleri.ornekler.ServiceResponseException; – Richard