@ -19,7 +19,9 @@ package org.springframework.web.servlet.mvc.method.annotation;
@@ -19,7 +19,9 @@ package org.springframework.web.servlet.mvc.method.annotation;
import java.io.IOException ;
import java.io.UnsupportedEncodingException ;
import java.io.Writer ;
import java.net.SocketTimeoutException ;
import java.util.Collections ;
import java.util.Locale ;
import org.junit.jupiter.api.BeforeAll ;
import org.junit.jupiter.api.BeforeEach ;
@ -30,8 +32,11 @@ import org.springframework.beans.FatalBeanException;
@@ -30,8 +32,11 @@ import org.springframework.beans.FatalBeanException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext ;
import org.springframework.context.annotation.Bean ;
import org.springframework.context.annotation.Configuration ;
import org.springframework.context.i18n.LocaleContextHolder ;
import org.springframework.context.support.StaticApplicationContext ;
import org.springframework.core.MethodParameter ;
import org.springframework.core.annotation.Order ;
import org.springframework.http.HttpStatus ;
import org.springframework.http.MediaType ;
import org.springframework.http.converter.HttpMessageConverter ;
import org.springframework.http.server.ServerHttpRequest ;
@ -42,6 +47,7 @@ import org.springframework.util.ClassUtils;
@@ -42,6 +47,7 @@ import org.springframework.util.ClassUtils;
import org.springframework.web.HttpRequestHandler ;
import org.springframework.web.bind.annotation.ExceptionHandler ;
import org.springframework.web.bind.annotation.ResponseBody ;
import org.springframework.web.bind.annotation.ResponseStatus ;
import org.springframework.web.bind.annotation.RestControllerAdvice ;
import org.springframework.web.context.support.WebApplicationObjectSupport ;
import org.springframework.web.method.HandlerMethod ;
@ -333,6 +339,28 @@ public class ExceptionHandlerExceptionResolverTests {
@@ -333,6 +339,28 @@ public class ExceptionHandlerExceptionResolverTests {
assertThat ( this . response . getContentAsString ( ) ) . isEqualTo ( rootCause . toString ( ) ) ;
}
@Test //gh-27156
void resolveExceptionWithReasonResovledByMessageSource ( ) throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext ( MyConfig . class ) ;
StaticApplicationContext context = new StaticApplicationContext ( ctx ) ;
Locale locale = Locale . ENGLISH ;
context . addMessage ( "gateway.timeout" , locale , "Gateway Timeout" ) ;
context . refresh ( ) ;
LocaleContextHolder . setLocale ( locale ) ;
this . resolver . setApplicationContext ( context ) ;
this . resolver . afterPropertiesSet ( ) ;
SocketTimeoutException ex = new SocketTimeoutException ( ) ;
HandlerMethod handlerMethod = new HandlerMethod ( new ResponseBodyController ( ) , "handle" ) ;
ModelAndView mav = this . resolver . resolveException ( this . request , this . response , handlerMethod , ex ) ;
assertThat ( mav ) . as ( "Exception was not handled" ) . isNotNull ( ) ;
assertThat ( mav . isEmpty ( ) ) . isTrue ( ) ;
assertThat ( this . response . getStatus ( ) ) . isEqualTo ( HttpStatus . GATEWAY_TIMEOUT . value ( ) ) ;
assertThat ( this . response . getErrorMessage ( ) ) . isEqualTo ( "Gateway Timeout" ) ;
assertThat ( this . response . getContentAsString ( ) ) . isEqualTo ( "" ) ;
}
@Test
void resolveExceptionControllerAdviceHandler ( ) throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext ( MyControllerAdviceConfig . class ) ;
@ -530,6 +558,16 @@ public class ExceptionHandlerExceptionResolverTests {
@@ -530,6 +558,16 @@ public class ExceptionHandlerExceptionResolverTests {
}
}
@RestControllerAdvice
@Order ( 3 )
static class ResponseStatusTestExceptionResolver {
@ExceptionHandler ( SocketTimeoutException . class )
@ResponseStatus ( code = HttpStatus . GATEWAY_TIMEOUT , reason = "gateway.timeout" )
public void handleException ( SocketTimeoutException ex ) {
}
}
@Configuration
static class MyConfig {
@ -543,6 +581,11 @@ public class ExceptionHandlerExceptionResolverTests {
@@ -543,6 +581,11 @@ public class ExceptionHandlerExceptionResolverTests {
public AnotherTestExceptionResolver anotherTestExceptionResolver ( ) {
return new AnotherTestExceptionResolver ( ) ;
}
@Bean
public ResponseStatusTestExceptionResolver responseStatusTestExceptionResolver ( ) {
return new ResponseStatusTestExceptionResolver ( ) ;
}
}