Skip to content

Commit 6a9fc39

Browse files
committed
Guard against instantiation errors in ValidationHelper
Prior to this commit, the `ValidationHelper` would fetch a `Validator` implementation from the application context and unwrap it if necessary in `createIfValidatorPresent`. This strategy can fail in the case of a `OptionalLocalValidatorFactoryBean` bean when unwrapping, if the jakarta validation API is on the classpath but no concrete provider is present. This commit ensures that exceptions thrown during the unwrapping phase are ignored and a `null` `ValidationHelper` is returned for those cases. Fixes gh-1407
1 parent 17a57a9 commit 6a9fc39

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ValidationHelper.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,16 @@ else if (annot.annotationType().equals(Validated.class)) {
119119
*/
120120
static @Nullable ValidationHelper createIfValidatorPresent(ApplicationContext context) {
121121
Validator validator = context.getBeanProvider(Validator.class).getIfAvailable();
122-
if (validator instanceof LocalValidatorFactoryBean) {
123-
validator = ((LocalValidatorFactoryBean) validator).getValidator();
122+
try {
123+
if (validator instanceof LocalValidatorFactoryBean) {
124+
validator = ((LocalValidatorFactoryBean) validator).getValidator();
125+
}
126+
else if (validator instanceof SpringValidatorAdapter) {
127+
validator = validator.unwrap(Validator.class);
128+
}
124129
}
125-
else if (validator instanceof SpringValidatorAdapter) {
126-
validator = validator.unwrap(Validator.class);
130+
catch (Exception exc) {
131+
return null;
127132
}
128133
return (validator != null) ? create(validator) : null;
129134
}

spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ValidationHelperTests.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,16 @@
3636
import org.junit.jupiter.api.Test;
3737

3838
import org.springframework.beans.BeanUtils;
39+
import org.springframework.context.support.StaticApplicationContext;
3940
import org.springframework.graphql.data.ArgumentValue;
4041
import org.springframework.graphql.data.method.HandlerMethod;
4142
import org.springframework.validation.annotation.Validated;
43+
import org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean;
4244

4345
import static org.assertj.core.api.Assertions.assertThat;
4446
import static org.assertj.core.api.Assertions.assertThatThrownBy;
47+
import static org.mockito.BDDMockito.given;
48+
import static org.mockito.Mockito.mock;
4549

4650
/**
4751
* Unit tests for {@link ValidationHelper}.
@@ -55,6 +59,15 @@ void shouldFailWithNullValidator() {
5559
assertThatThrownBy(() -> ValidationHelper.create(null)).isInstanceOf(IllegalArgumentException.class);
5660
}
5761

62+
@Test
63+
void shouldReturnNullValidatorWhenInstantiationFailure() {
64+
OptionalValidatorFactoryBean validatorFactory = mock(OptionalValidatorFactoryBean.class);
65+
given(validatorFactory.getValidator()).willThrow(new IllegalStateException("No target ValidatorFactory set"));
66+
StaticApplicationContext applicationContext = new StaticApplicationContext();
67+
applicationContext.registerBean(Validator.class, () -> validatorFactory);
68+
assertThat(ValidationHelper.createIfValidatorPresent(applicationContext)).isNull();
69+
}
70+
5871
@Test
5972
void shouldIgnoreMethodsWithoutAnnotations() {
6073
assertThat(validateFunction(MyBean.class, "notValidatedMethod")).isNull();

0 commit comments

Comments
 (0)