Skip to content

Commit 5cb1930

Browse files
committed
Fix issue in Callable processing interceptor chain
1 parent 79edf62 commit 5cb1930

File tree

4 files changed

+43
-6
lines changed

4 files changed

+43
-6
lines changed

spring-web/src/main/java/org/springframework/web/context/request/async/CallableInterceptorChain.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,22 @@ public void applyPreProcess(NativeWebRequest request, Callable<?> task) throws E
4949
}
5050

5151
public Object applyPostProcess(NativeWebRequest request, Callable<?> task, Object concurrentResult) {
52+
Throwable exceptionResult = null;
5253
for (int i = this.preProcessIndex; i >= 0; i--) {
5354
try {
5455
this.interceptors.get(i).postProcess(request, task, concurrentResult);
5556
}
5657
catch (Throwable t) {
57-
return t;
58+
// Save the first exception but invoke all interceptors
59+
if (exceptionResult != null) {
60+
logger.error("postProcess error", t);
61+
}
62+
else {
63+
exceptionResult = t;
64+
}
5865
}
5966
}
60-
return concurrentResult;
67+
return (exceptionResult != null) ? exceptionResult : concurrentResult;
6168
}
6269

6370
public Object triggerAfterTimeout(NativeWebRequest request, Callable<?> task) {

spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ public void registerCallableInterceptor(Object key, CallableProcessingIntercepto
197197
* The key is derived from the class name and hashcode.
198198
* @param interceptor the interceptor to register
199199
*/
200-
public void registerCallableInterceptor(CallableProcessingInterceptor... interceptors) {
200+
public void registerCallableInterceptors(CallableProcessingInterceptor... interceptors) {
201201
Assert.notNull(interceptors, "A CallableProcessingInterceptor is required");
202202
for (CallableProcessingInterceptor interceptor : interceptors) {
203203
String key = interceptor.getClass().getName() + ":" + interceptor.hashCode();
@@ -222,7 +222,7 @@ public void registerDeferredResultInterceptor(Object key, DeferredResultProcessi
222222
* @param key the key
223223
* @param interceptors the interceptor to register
224224
*/
225-
public void registerDeferredResultInterceptor(DeferredResultProcessingInterceptor... interceptors) {
225+
public void registerDeferredResultInterceptors(DeferredResultProcessingInterceptor... interceptors) {
226226
Assert.notNull(interceptors, "A DeferredResultProcessingInterceptor is required");
227227
for (DeferredResultProcessingInterceptor interceptor : interceptors) {
228228
String key = interceptors.getClass().getName() + ":" + interceptors.hashCode();

spring-web/src/test/java/org/springframework/web/context/request/async/WebAsyncManagerTests.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,36 @@ public void startCallableProcessingPostProcessException() throws Exception {
200200
verify(interceptor, this.asyncWebRequest);
201201
}
202202

203+
@Test
204+
public void startCallableProcessingPostProcessContinueAfterException() throws Exception {
205+
206+
Callable<Object> task = new StubCallable(21);
207+
Exception exception = new Exception();
208+
209+
CallableProcessingInterceptor interceptor1 = createMock(CallableProcessingInterceptor.class);
210+
interceptor1.preProcess(this.asyncWebRequest, task);
211+
interceptor1.postProcess(this.asyncWebRequest, task, 21);
212+
replay(interceptor1);
213+
214+
CallableProcessingInterceptor interceptor2 = createMock(CallableProcessingInterceptor.class);
215+
interceptor2.preProcess(this.asyncWebRequest, task);
216+
interceptor2.postProcess(this.asyncWebRequest, task, 21);
217+
expectLastCall().andThrow(exception);
218+
replay(interceptor2);
219+
220+
setupDefaultAsyncScenario();
221+
222+
this.asyncManager.registerCallableInterceptors(interceptor1, interceptor2);
223+
this.asyncManager.startCallableProcessing(task);
224+
225+
assertTrue(this.asyncManager.hasConcurrentResult());
226+
assertEquals(exception, this.asyncManager.getConcurrentResult());
227+
228+
verify(interceptor1);
229+
verify(interceptor2);
230+
verify(this.asyncWebRequest);
231+
}
232+
203233
@Test
204234
public void startCallableProcessingWithAsyncTask() {
205235

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -728,8 +728,8 @@ private ModelAndView invokeHandleMethod(HttpServletRequest request,
728728
final WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
729729
asyncManager.setTaskExecutor(this.taskExecutor);
730730
asyncManager.setAsyncWebRequest(asyncWebRequest);
731-
asyncManager.registerCallableInterceptor(this.callableInterceptors);
732-
asyncManager.registerDeferredResultInterceptor(this.deferredResultInterceptors);
731+
asyncManager.registerCallableInterceptors(this.callableInterceptors);
732+
asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);
733733

734734
if (asyncManager.hasConcurrentResult()) {
735735
Object result = asyncManager.getConcurrentResult();

0 commit comments

Comments
 (0)