mirror of
https://github.com/spring-projects/spring-framework.git
synced 2024-10-23 07:05:25 +08:00
Default webmvc handling of disconnected client errors
Closes gh-33753
This commit is contained in:
parent
5271f5b8a1
commit
9252e741e1
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -31,6 +31,7 @@ import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.util.DisconnectedClientHelper;
|
||||
|
||||
/**
|
||||
* Abstract base class for {@link HandlerExceptionResolver} implementations.
|
||||
@ -48,6 +49,12 @@ public abstract class AbstractHandlerExceptionResolver implements HandlerExcepti
|
||||
|
||||
private static final String HEADER_CACHE_CONTROL = "Cache-Control";
|
||||
|
||||
private static final String DISCONNECTED_CLIENT_LOG_CATEGORY =
|
||||
"org.springframework.web.servlet.handler.DisconnectedClient";
|
||||
|
||||
private static final DisconnectedClientHelper disconnectedClientHelper =
|
||||
new DisconnectedClientHelper(DISCONNECTED_CLIENT_LOG_CATEGORY);
|
||||
|
||||
|
||||
/** Logger available to subclasses. */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
@ -173,7 +180,7 @@ public abstract class AbstractHandlerExceptionResolver implements HandlerExcepti
|
||||
if (shouldApplyTo(request, handler)) {
|
||||
prepareResponse(ex, response);
|
||||
ModelAndView result = doResolveException(request, response, handler, ex);
|
||||
if (result != null) {
|
||||
if (result != null && !disconnectedClientHelper.checkAndLogClientDisconnectedException(ex)) {
|
||||
// Print debug message when warn logger is not enabled.
|
||||
if (logger.isDebugEnabled() && (this.warnLogger == null || !this.warnLogger.isWarnEnabled())) {
|
||||
logger.debug(buildLogMessage(ex, request) + (result.isEmpty() ? "" : " to " + result));
|
||||
|
@ -51,6 +51,7 @@ import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||
import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.resource.NoResourceFoundException;
|
||||
import org.springframework.web.util.DisconnectedClientHelper;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
/**
|
||||
@ -246,6 +247,9 @@ public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionRes
|
||||
return handleAsyncRequestNotUsableException(
|
||||
(AsyncRequestNotUsableException) ex, request, response, handler);
|
||||
}
|
||||
else if (DisconnectedClientHelper.isClientDisconnectedException(ex)) {
|
||||
return handleDisconnectedClientException(ex, request, response, handler);
|
||||
}
|
||||
}
|
||||
catch (Exception handlerEx) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
@ -514,6 +518,26 @@ public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionRes
|
||||
return new ModelAndView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an Exception that indicates the client has gone away. This is
|
||||
* typically an {@link IOException} of a specific subtype or with a message
|
||||
* specific to the underlying Servlet container. Those are detected through
|
||||
* {@link DisconnectedClientHelper#isClientDisconnectedException(Throwable)}
|
||||
* <p>By default, do nothing since the response is not usable.
|
||||
* @param ex the {@code Exception} to be handled
|
||||
* @param request current HTTP request
|
||||
* @param response current HTTP response
|
||||
* @param handler the executed handler, or {@code null} if none chosen
|
||||
* at the time of the exception (for example, if multipart resolution failed)
|
||||
* @return an empty ModelAndView indicating the exception was handled
|
||||
* @since 6.2
|
||||
*/
|
||||
protected ModelAndView handleDisconnectedClientException(
|
||||
Exception ex, HttpServletRequest request, HttpServletResponse response, @Nullable Object handler) {
|
||||
|
||||
return new ModelAndView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an {@link ErrorResponse} exception.
|
||||
* <p>The default implementation sets status and the headers of the response
|
||||
|
@ -107,6 +107,7 @@ class ResponseEntityExceptionHandlerTests {
|
||||
Arrays.stream(DefaultHandlerExceptionResolver.class.getDeclaredMethods())
|
||||
.filter(method -> method.getName().startsWith("handle") && (method.getParameterCount() == 4))
|
||||
.filter(method -> !method.getName().equals("handleErrorResponse"))
|
||||
.filter(method -> !method.getName().equals("handleDisconnectedClientException"))
|
||||
.map(method -> method.getParameterTypes()[0])
|
||||
.forEach(exceptionType -> assertThat(annotation.value())
|
||||
.as("@ExceptionHandler is missing declaration for " + exceptionType.getName())
|
||||
|
Loading…
Reference in New Issue
Block a user