diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java index b965a2f0f3..05e87092b2 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java @@ -91,7 +91,7 @@ public class ServletHttpHandlerAdapter extends HttpServlet { servletRequest, this.dataBufferFactory, this.bufferSize); ServletServerHttpResponse response = new ServletServerHttpResponse( servletResponse, this.dataBufferFactory, this.bufferSize); - asyncContext.addListener(new HandlerAsyncEvent(request, response)); + asyncContext.addListener(new ErrorHandlingAsyncListener(request, response)); HandlerResultSubscriber resultSubscriber = new HandlerResultSubscriber(asyncContext); this.handler.handle(request, response).subscribe(resultSubscriber); } @@ -130,40 +130,47 @@ public class ServletHttpHandlerAdapter extends HttpServlet { } } - private static final class HandlerAsyncEvent implements AsyncListener { + + private static final class ErrorHandlingAsyncListener implements AsyncListener { + private final ServletServerHttpRequest request; + private final ServletServerHttpResponse response; - public HandlerAsyncEvent(ServletServerHttpRequest request, + + public ErrorHandlingAsyncListener(ServletServerHttpRequest request, ServletServerHttpResponse response) { + this.request = request; this.response = response; } + @Override - public void onComplete(AsyncEvent event) throws IOException { + public void onTimeout(AsyncEvent event) { + Throwable ex = event.getThrowable(); + if (ex == null) { + ex = new IllegalStateException("Async operation timeout."); + } + this.request.handleAsyncListenerError(ex); + this.response.handleAsyncListenerError(ex); + } + + @Override + public void onError(AsyncEvent event) { + this.request.handleAsyncListenerError(event.getThrowable()); + this.response.handleAsyncListenerError(event.getThrowable()); + } + + @Override + public void onStartAsync(AsyncEvent event) { // no op } @Override - public void onTimeout(AsyncEvent event) throws IOException { - Throwable t = event.getThrowable(); - if (t == null) { - t = new IllegalStateException("Async operation timeout."); - } - request.onError(t); - response.onError(t); - } - - @Override - public void onError(AsyncEvent event) throws IOException { - request.onError(event.getThrowable()); - response.onError(event.getThrowable()); - } - - @Override - public void onStartAsync(AsyncEvent event) throws IOException { + public void onComplete(AsyncEvent event) { // no op } } + } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java index 65a22d078a..acbf881b10 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java @@ -170,9 +170,10 @@ public class ServletServerHttpRequest extends AbstractServerHttpRequest { } } - void onError(Throwable t) { + /** Handle a timeout/error callback from the Servlet container */ + void handleAsyncListenerError(Throwable ex) { if (this.bodyPublisher != null) { - this.bodyPublisher.onError(t); + this.bodyPublisher.onError(ex); } } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java index 7233f41775..2ff1ff99ec 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java @@ -154,15 +154,15 @@ public class ServletServerHttpResponse extends AbstractListenerServerHttpRespons } } - - void onError(Throwable t) { - if (bodyFlushProcessor != null) { - bodyFlushProcessor.cancel(); - bodyFlushProcessor.onError(t); + /** Handle a timeout/error callback from the Servlet container */ + void handleAsyncListenerError(Throwable ex) { + if (this.bodyFlushProcessor != null) { + this.bodyFlushProcessor.cancel(); + this.bodyFlushProcessor.onError(ex); } - if (bodyProcessor != null) { - bodyProcessor.cancel(); - bodyProcessor.onError(t); + if (this.bodyProcessor != null) { + this.bodyProcessor.cancel(); + this.bodyProcessor.onError(ex); } }