Fall back on */* during content negotiation for errors
Prior to this commit, gh-31936 enabled content negotiation for `@ExceptionHandler` annotated methods in Spring MVC and WebFlux. In the case of WebFlux, HTTP clients sending invalid media types in the "Accept" request header would fail with a `NotAcceptableStatusException` This exception would be handled with an HTTP 406 response status, instead of processing the original exception. This commit ensures that invalid media types are ignored during the exception handling phase and that we fall back to "*/*". Fixes gh-32878
This commit is contained in:
parent
94348d9d41
commit
51f6e78e25
|
|
@ -60,6 +60,7 @@ import org.springframework.web.reactive.result.method.HandlerMethodArgumentResol
|
||||||
import org.springframework.web.reactive.result.method.InvocableHandlerMethod;
|
import org.springframework.web.reactive.result.method.InvocableHandlerMethod;
|
||||||
import org.springframework.web.reactive.result.method.SyncHandlerMethodArgumentResolver;
|
import org.springframework.web.reactive.result.method.SyncHandlerMethodArgumentResolver;
|
||||||
import org.springframework.web.reactive.result.method.SyncInvocableHandlerMethod;
|
import org.springframework.web.reactive.result.method.SyncInvocableHandlerMethod;
|
||||||
|
import org.springframework.web.server.NotAcceptableStatusException;
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -416,7 +417,15 @@ class ControllerMethodResolver {
|
||||||
public InvocableHandlerMethod getExceptionHandlerMethod(Throwable ex, ServerWebExchange exchange, @Nullable HandlerMethod handlerMethod) {
|
public InvocableHandlerMethod getExceptionHandlerMethod(Throwable ex, ServerWebExchange exchange, @Nullable HandlerMethod handlerMethod) {
|
||||||
|
|
||||||
Class<?> handlerType = (handlerMethod != null ? handlerMethod.getBeanType() : null);
|
Class<?> handlerType = (handlerMethod != null ? handlerMethod.getBeanType() : null);
|
||||||
List<MediaType> requestedMediaTypes = this.contentTypeResolver.resolveMediaTypes(exchange);
|
List<MediaType> requestedMediaTypes = List.of(MediaType.ALL);
|
||||||
|
try {
|
||||||
|
requestedMediaTypes = this.contentTypeResolver.resolveMediaTypes(exchange);
|
||||||
|
}
|
||||||
|
catch (NotAcceptableStatusException exc) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Could not parse Accept header for requested media types", exc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Controller-local first
|
// Controller-local first
|
||||||
if (handlerType != null) {
|
if (handlerType != null) {
|
||||||
|
|
|
||||||
|
|
@ -258,6 +258,18 @@ class ControllerMethodResolverTests {
|
||||||
assertThat(producibleMediaTypes).isNotEmpty().contains(MediaType.APPLICATION_JSON);
|
assertThat(producibleMediaTypes).isNotEmpty().contains(MediaType.APPLICATION_JSON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void exceptionHandlerWithInvalidAcceptHeader() {
|
||||||
|
Method method = ResolvableMethod.on(ExceptionHandlerController.class).mockCall(ExceptionHandlerController::handle).method();
|
||||||
|
this.handlerMethod = new HandlerMethod(new ExceptionHandlerController(), method);
|
||||||
|
MockServerHttpRequest httpRequest = MockServerHttpRequest.get("/test").header("Accept", "v=12").build();
|
||||||
|
MockServerWebExchange serverWebExchange = MockServerWebExchange.builder(httpRequest).build();
|
||||||
|
InvocableHandlerMethod invocable = this.methodResolver.getExceptionHandlerMethod(
|
||||||
|
new ResponseStatusException(HttpStatus.BAD_REQUEST, "reason"), serverWebExchange, this.handlerMethod);
|
||||||
|
|
||||||
|
assertThat(invocable).as("No match").isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static HandlerMethodArgumentResolver next(
|
private static HandlerMethodArgumentResolver next(
|
||||||
List<? extends HandlerMethodArgumentResolver> resolvers, AtomicInteger index) {
|
List<? extends HandlerMethodArgumentResolver> resolvers, AtomicInteger index) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue