@ -19,13 +19,16 @@ package org.springframework.boot.web.servlet.error;
@@ -19,13 +19,16 @@ package org.springframework.boot.web.servlet.error;
import java.lang.reflect.Method ;
import java.util.Collections ;
import java.util.Date ;
import java.util.List ;
import java.util.Map ;
import java.util.function.Supplier ;
import jakarta.servlet.ServletException ;
import org.junit.jupiter.api.Test ;
import org.springframework.boot.web.error.ErrorAttributeOptions ;
import org.springframework.boot.web.error.ErrorAttributeOptions.Include ;
import org.springframework.context.MessageSourceResolvable ;
import org.springframework.core.MethodParameter ;
import org.springframework.http.HttpStatus ;
import org.springframework.mock.web.MockHttpServletRequest ;
@ -34,9 +37,12 @@ import org.springframework.validation.BindException;
@@ -34,9 +37,12 @@ import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult ;
import org.springframework.validation.MapBindingResult ;
import org.springframework.validation.ObjectError ;
import org.springframework.validation.method.MethodValidationResult ;
import org.springframework.validation.method.ParameterValidationResult ;
import org.springframework.web.bind.MethodArgumentNotValidException ;
import org.springframework.web.context.request.ServletWebRequest ;
import org.springframework.web.context.request.WebRequest ;
import org.springframework.web.method.annotation.HandlerMethodValidationException ;
import org.springframework.web.servlet.ModelAndView ;
import static org.assertj.core.api.Assertions.assertThat ;
@ -47,6 +53,7 @@ import static org.assertj.core.api.Assertions.assertThat;
@@ -47,6 +53,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Phillip Webb
* @author Vedran Pavic
* @author Scott Frederick
* @author Yanming Zhou
* /
class DefaultErrorAttributesTests {
@ -201,18 +208,57 @@ class DefaultErrorAttributesTests {
@@ -201,18 +208,57 @@ class DefaultErrorAttributesTests {
testBindingResult ( bindingResult , ex , ErrorAttributeOptions . of ( Include . MESSAGE , Include . BINDING_ERRORS ) ) ;
}
@Test
void withHandlerMethodValidationExceptionBindingErrors ( ) {
Object target = "test" ;
Method method = ReflectionUtils . findMethod ( String . class , "substring" , int . class ) ;
MethodParameter parameter = new MethodParameter ( method , 0 ) ;
MethodValidationResult methodValidationResult = new MethodValidationResult ( ) {
@Override
public Object getTarget ( ) {
return target ;
}
@Override
public Method getMethod ( ) {
return method ;
}
@Override
public boolean isForReturnValue ( ) {
return false ;
}
@Override
public List < ParameterValidationResult > getAllValidationResults ( ) {
return List . of ( new ParameterValidationResult ( parameter , - 1 ,
List . of ( new ObjectError ( "beginIndex" , "beginIndex is negative" ) ) , null , null , null ) ) ;
}
} ;
HandlerMethodValidationException ex = new HandlerMethodValidationException ( methodValidationResult ) ;
testErrorsSupplier ( methodValidationResult : : getAllErrors ,
"Validation failed for method='public java.lang.String java.lang.String.substring(int)'. Error count: 1" ,
ex , ErrorAttributeOptions . of ( Include . MESSAGE , Include . BINDING_ERRORS ) ) ;
}
private void testBindingResult ( BindingResult bindingResult , Exception ex , ErrorAttributeOptions options ) {
testErrorsSupplier ( bindingResult : : getAllErrors , "Validation failed for object='objectName'. Error count: 1" , ex ,
options ) ;
}
private void testErrorsSupplier ( Supplier < List < ? extends MessageSourceResolvable > > errorsSupplier ,
String expectedMessage , Exception ex , ErrorAttributeOptions options ) {
this . request . setAttribute ( "jakarta.servlet.error.exception" , ex ) ;
Map < String , Object > attributes = this . errorAttributes . getErrorAttributes ( this . webRequest , options ) ;
if ( options . isIncluded ( Include . MESSAGE ) ) {
assertThat ( attributes ) . containsEntry ( "message" ,
"Validation failed for object='objectName'. Error count: 1" ) ;
assertThat ( attributes ) . containsEntry ( "message" , expectedMessage ) ;
}
else {
assertThat ( attributes ) . doesNotContainKey ( "message" ) ;
}
if ( options . isIncluded ( Include . BINDING_ERRORS ) ) {
assertThat ( attributes ) . containsEntry ( "errors" , bindingResult . getAllErrors ( ) ) ;
assertThat ( attributes ) . containsEntry ( "errors" , errorsSupplier . get ( ) ) ;
}
else {
assertThat ( attributes ) . doesNotContainKey ( "errors" ) ;