Better handling for AsyncRequestTimeoutException
Avoid call to sendError when response is committed and log a short error message instead. Issue: SPR-14739
This commit is contained in:
parent
b1030eba3f
commit
afcc120b97
|
@ -18,6 +18,8 @@ package org.springframework.web.servlet.mvc.method.annotation;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
@ -43,6 +45,7 @@ import org.springframework.web.bind.MissingServletRequestParameterException;
|
||||||
import org.springframework.web.bind.ServletRequestBindingException;
|
import org.springframework.web.bind.ServletRequestBindingException;
|
||||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.context.request.ServletWebRequest;
|
||||||
import org.springframework.web.context.request.WebRequest;
|
import org.springframework.web.context.request.WebRequest;
|
||||||
import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
|
import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
|
||||||
import org.springframework.web.multipart.support.MissingServletRequestPartException;
|
import org.springframework.web.multipart.support.MissingServletRequestPartException;
|
||||||
|
@ -439,14 +442,23 @@ public abstract class ResponseEntityExceptionHandler {
|
||||||
* @param ex the exception
|
* @param ex the exception
|
||||||
* @param headers the headers to be written to the response
|
* @param headers the headers to be written to the response
|
||||||
* @param status the selected response status
|
* @param status the selected response status
|
||||||
* @param request the current request
|
* @param webRequest the current request
|
||||||
* @return a {@code ResponseEntity} instance
|
* @return a {@code ResponseEntity} instance
|
||||||
* @since 4.2.8
|
* @since 4.2.8
|
||||||
*/
|
*/
|
||||||
protected ResponseEntity<Object> handleAsyncRequestTimeoutException(
|
protected ResponseEntity<Object> handleAsyncRequestTimeoutException(
|
||||||
AsyncRequestTimeoutException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
|
AsyncRequestTimeoutException ex, HttpHeaders headers, HttpStatus status, WebRequest webRequest) {
|
||||||
|
|
||||||
return handleExceptionInternal(ex, null, headers, status, request);
|
if (webRequest instanceof ServletWebRequest) {
|
||||||
|
ServletWebRequest servletRequest = (ServletWebRequest) webRequest;
|
||||||
|
HttpServletRequest request = servletRequest.getNativeRequest(HttpServletRequest.class);
|
||||||
|
HttpServletResponse response = servletRequest.getNativeResponse(HttpServletResponse.class);
|
||||||
|
if (response.isCommitted()) {
|
||||||
|
logger.error("Async timeout for " + request.getMethod() + " [" + request.getRequestURI() + "]");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return handleExceptionInternal(ex, null, headers, status, webRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -469,7 +469,12 @@ public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionRes
|
||||||
protected ModelAndView handleAsyncRequestTimeoutException(AsyncRequestTimeoutException ex,
|
protected ModelAndView handleAsyncRequestTimeoutException(AsyncRequestTimeoutException ex,
|
||||||
HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
|
HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
|
||||||
|
|
||||||
|
if (!response.isCommitted()) {
|
||||||
response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
|
response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
|
||||||
|
}
|
||||||
|
else if (logger.isErrorEnabled()) {
|
||||||
|
logger.error("Async timeout for " + request.getMethod() + " [" + request.getRequestURI() + "]");
|
||||||
|
}
|
||||||
return new ModelAndView();
|
return new ModelAndView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,6 +486,7 @@ public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionRes
|
||||||
protected void sendServerError(Exception ex, HttpServletRequest request, HttpServletResponse response)
|
protected void sendServerError(Exception ex, HttpServletRequest request, HttpServletResponse response)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
|
|
||||||
request.setAttribute("javax.servlet.error.exception", ex);
|
request.setAttribute("javax.servlet.error.exception", ex);
|
||||||
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue