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