diff --git a/spring-web/src/main/java/org/springframework/web/context/request/async/DeferredResultInterceptorChain.java b/spring-web/src/main/java/org/springframework/web/context/request/async/DeferredResultInterceptorChain.java index b87fc43ee4..5576e79b6a 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/async/DeferredResultInterceptorChain.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/async/DeferredResultInterceptorChain.java @@ -82,17 +82,22 @@ class DeferredResultInterceptorChain { } } - public void triggerAfterError(NativeWebRequest request, DeferredResult deferredResult, Throwable ex) + /** + * @return true to continue error handling, or false to bypass any further + * error handling + */ + public boolean triggerAfterError(NativeWebRequest request, DeferredResult deferredResult, Throwable ex) throws Exception { for (DeferredResultProcessingInterceptor interceptor : this.interceptors) { if (deferredResult.isSetOrExpired()) { - return; + return false; } if (!interceptor.handleError(request, deferredResult, ex)){ - break; + return false; } } + return true; } public void triggerAfterCompletion(NativeWebRequest request, DeferredResult deferredResult) { diff --git a/spring-web/src/main/java/org/springframework/web/context/request/async/DeferredResultProcessingInterceptor.java b/spring-web/src/main/java/org/springframework/web/context/request/async/DeferredResultProcessingInterceptor.java index b601df1219..98a597e8ef 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/async/DeferredResultProcessingInterceptor.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/async/DeferredResultProcessingInterceptor.java @@ -114,8 +114,8 @@ public interface DeferredResultProcessingInterceptor { * {@code DeferredResult} is set, then concurrent processing is resumed and * subsequent interceptors are not invoked * @param t the error that occurred while request processing - * @return {@code true} if processing should continue, or {@code false} if - * other interceptors should not be invoked + * @return {@code true} if error handling should continue, or {@code false} if + * other interceptors should by bypassed and not be invoked * @throws Exception in case of errors */ default boolean handleError(NativeWebRequest request, DeferredResult deferredResult, diff --git a/spring-web/src/main/java/org/springframework/web/context/request/async/ErrorCallableProcessingInterceptor.java b/spring-web/src/main/java/org/springframework/web/context/request/async/ErrorCallableProcessingInterceptor.java deleted file mode 100644 index 1b012595ae..0000000000 --- a/spring-web/src/main/java/org/springframework/web/context/request/async/ErrorCallableProcessingInterceptor.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.context.request.async; - -import java.util.concurrent.Callable; - -import org.springframework.web.context.request.NativeWebRequest; - -/** - * Registered at the end, after all other interceptors and - * therefore invoked only if no other interceptor handles the error. - * - * @author Violeta Georgieva - * @since 5.0 - */ -class ErrorCallableProcessingInterceptor implements CallableProcessingInterceptor { - - @Override - public Object handleError(NativeWebRequest request, Callable task, Throwable t) throws Exception { - return t; - } - -} diff --git a/spring-web/src/main/java/org/springframework/web/context/request/async/ErrorDeferredResultProcessingInterceptor.java b/spring-web/src/main/java/org/springframework/web/context/request/async/ErrorDeferredResultProcessingInterceptor.java deleted file mode 100644 index ce1f853647..0000000000 --- a/spring-web/src/main/java/org/springframework/web/context/request/async/ErrorDeferredResultProcessingInterceptor.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.context.request.async; - -import org.springframework.web.context.request.NativeWebRequest; - -/** - * Registered at the end, after all other interceptors and - * therefore invoked only if no other interceptor handles the error. - * - * @author Violeta Georgieva - * @since 5.0 - */ -public class ErrorDeferredResultProcessingInterceptor implements DeferredResultProcessingInterceptor { - - @Override - public boolean handleError(NativeWebRequest request, DeferredResult result, Throwable t) - throws Exception { - - result.setErrorResult(t); - return false; - } - -} diff --git a/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java b/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java index 1a525dbaba..52a09bf146 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java @@ -68,15 +68,9 @@ public final class WebAsyncManager { private static final CallableProcessingInterceptor timeoutCallableInterceptor = new TimeoutCallableProcessingInterceptor(); - private static final CallableProcessingInterceptor errorCallableInterceptor = - new ErrorCallableProcessingInterceptor(); - private static final DeferredResultProcessingInterceptor timeoutDeferredResultInterceptor = new TimeoutDeferredResultProcessingInterceptor(); - private static final DeferredResultProcessingInterceptor errorDeferredResultInterceptor = - new ErrorDeferredResultProcessingInterceptor(); - private AsyncWebRequest asyncWebRequest; @@ -290,7 +284,6 @@ public final class WebAsyncManager { interceptors.add(webAsyncTask.getInterceptor()); interceptors.addAll(this.callableInterceptors.values()); interceptors.add(timeoutCallableInterceptor); - interceptors.add(errorCallableInterceptor); final Callable callable = webAsyncTask.getCallable(); final CallableInterceptorChain interceptorChain = new CallableInterceptorChain(interceptors); @@ -303,12 +296,11 @@ public final class WebAsyncManager { } }); - this.asyncWebRequest.addErrorHandler(t -> { + this.asyncWebRequest.addErrorHandler(ex -> { logger.debug("Processing error"); - Object result = interceptorChain.triggerAfterError(this.asyncWebRequest, callable, t); - if (result != CallableProcessingInterceptor.RESULT_NONE) { - setConcurrentResultAndDispatch(result); - } + Object result = interceptorChain.triggerAfterError(this.asyncWebRequest, callable, ex); + result = (result != CallableProcessingInterceptor.RESULT_NONE ? result : ex); + setConcurrentResultAndDispatch(result); }); this.asyncWebRequest.addCompletionHandler(() -> @@ -390,7 +382,6 @@ public final class WebAsyncManager { interceptors.add(deferredResult.getInterceptor()); interceptors.addAll(this.deferredResultInterceptors.values()); interceptors.add(timeoutDeferredResultInterceptor); - interceptors.add(errorDeferredResultInterceptor); final DeferredResultInterceptorChain interceptorChain = new DeferredResultInterceptorChain(interceptors); @@ -403,12 +394,15 @@ public final class WebAsyncManager { } }); - this.asyncWebRequest.addErrorHandler(t -> { + this.asyncWebRequest.addErrorHandler(ex -> { try { - interceptorChain.triggerAfterError(this.asyncWebRequest, deferredResult, t); + if (!interceptorChain.triggerAfterError(this.asyncWebRequest, deferredResult, ex)) { + return; + } + deferredResult.setErrorResult(ex); } - catch (Throwable ex) { - setConcurrentResultAndDispatch(ex); + catch (Throwable interceptorEx) { + setConcurrentResultAndDispatch(interceptorEx); } });