Skip to content

Commit fe333e4

Browse files
committed
Better handling for AsyncRequestTimeoutException
Avoid call to sendError when response is committed and log a short error message instead. Issue: SPR-14739
1 parent 0254102 commit fe333e4

File tree

2 files changed

+23
-5
lines changed

2 files changed

+23
-5
lines changed

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

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import java.util.List;
2020
import java.util.Set;
21+
import javax.servlet.http.HttpServletRequest;
22+
import javax.servlet.http.HttpServletResponse;
2123

2224
import org.apache.commons.logging.Log;
2325
import org.apache.commons.logging.LogFactory;
@@ -43,6 +45,7 @@
4345
import org.springframework.web.bind.ServletRequestBindingException;
4446
import org.springframework.web.bind.annotation.ControllerAdvice;
4547
import org.springframework.web.bind.annotation.ExceptionHandler;
48+
import org.springframework.web.context.request.ServletWebRequest;
4649
import org.springframework.web.context.request.WebRequest;
4750
import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
4851
import org.springframework.web.multipart.support.MissingServletRequestPartException;
@@ -462,14 +465,23 @@ protected ResponseEntity<Object> handleNoHandlerFoundException(
462465
* @param ex the exception
463466
* @param headers the headers to be written to the response
464467
* @param status the selected response status
465-
* @param request the current request
468+
* @param webRequest the current request
466469
* @return a {@code ResponseEntity} instance
467470
* @since 4.2.8
468471
*/
469472
protected ResponseEntity<Object> handleAsyncRequestTimeoutException(
470-
AsyncRequestTimeoutException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
471-
472-
return handleExceptionInternal(ex, null, headers, status, request);
473+
AsyncRequestTimeoutException ex, HttpHeaders headers, HttpStatus status, WebRequest webRequest) {
474+
475+
if (webRequest instanceof ServletWebRequest) {
476+
ServletWebRequest servletRequest = (ServletWebRequest) webRequest;
477+
HttpServletRequest request = servletRequest.getNativeRequest(HttpServletRequest.class);
478+
HttpServletResponse response = servletRequest.getNativeResponse(HttpServletResponse.class);
479+
if (response.isCommitted()) {
480+
logger.error("Async timeout for " + request.getMethod() + " [" + request.getRequestURI() + "]");
481+
return null;
482+
}
483+
}
484+
return handleExceptionInternal(ex, null, headers, status, webRequest);
473485
}
474486

475487
}

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,12 @@ protected ModelAndView handleNoHandlerFoundException(NoHandlerFoundException ex,
496496
protected ModelAndView handleAsyncRequestTimeoutException(AsyncRequestTimeoutException ex,
497497
HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
498498

499-
response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
499+
if (!response.isCommitted()) {
500+
response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
501+
}
502+
else if (logger.isErrorEnabled()) {
503+
logger.error("Async timeout for " + request.getMethod() + " [" + request.getRequestURI() + "]");
504+
}
500505
return new ModelAndView();
501506
}
502507

@@ -508,6 +513,7 @@ protected ModelAndView handleAsyncRequestTimeoutException(AsyncRequestTimeoutExc
508513
protected void sendServerError(Exception ex, HttpServletRequest request, HttpServletResponse response)
509514
throws IOException {
510515

516+
511517
request.setAttribute("javax.servlet.error.exception", ex);
512518
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
513519
}

0 commit comments

Comments
 (0)