Skip to content

Commit 45b8cf3

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 2c2c6f8 commit 45b8cf3

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;
@@ -464,14 +467,23 @@ protected ResponseEntity<Object> handleNoHandlerFoundException(
464467
* @param ex the exception
465468
* @param headers the headers to be written to the response
466469
* @param status the selected response status
467-
* @param request the current request
470+
* @param webRequest the current request
468471
* @return a {@code ResponseEntity} instance
469472
* @since 4.2.8
470473
*/
471474
protected ResponseEntity<Object> handleAsyncRequestTimeoutException(
472-
AsyncRequestTimeoutException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
473-
474-
return handleExceptionInternal(ex, null, headers, status, request);
475+
AsyncRequestTimeoutException ex, HttpHeaders headers, HttpStatus status, WebRequest webRequest) {
476+
477+
if (webRequest instanceof ServletWebRequest) {
478+
ServletWebRequest servletRequest = (ServletWebRequest) webRequest;
479+
HttpServletRequest request = servletRequest.getNativeRequest(HttpServletRequest.class);
480+
HttpServletResponse response = servletRequest.getNativeResponse(HttpServletResponse.class);
481+
if (response.isCommitted()) {
482+
logger.error("Async timeout for " + request.getMethod() + " [" + request.getRequestURI() + "]");
483+
return null;
484+
}
485+
}
486+
return handleExceptionInternal(ex, null, headers, status, webRequest);
475487
}
476488

477489
}

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
@@ -498,7 +498,12 @@ protected ModelAndView handleNoHandlerFoundException(NoHandlerFoundException ex,
498498
protected ModelAndView handleAsyncRequestTimeoutException(AsyncRequestTimeoutException ex,
499499
HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
500500

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

@@ -510,6 +515,7 @@ protected ModelAndView handleAsyncRequestTimeoutException(AsyncRequestTimeoutExc
510515
protected void sendServerError(Exception ex, HttpServletRequest request, HttpServletResponse response)
511516
throws IOException {
512517

518+
513519
request.setAttribute("javax.servlet.error.exception", ex);
514520
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
515521
}

0 commit comments

Comments
 (0)