Skip to content

Commit

Permalink
Construct consistent error messages in BeanOverrideBeanFactoryPostPro…
Browse files Browse the repository at this point in the history
…cessor
  • Loading branch information
sbrannen committed Nov 21, 2024
1 parent 08a789c commit b9cf03f
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ private void replaceOrCreateBean(ConfigurableListableBeanFactory beanFactory, Be
// 3) AOT runtime

String beanName = handler.getBeanName();
Field field = handler.getField();
BeanDefinition existingBeanDefinition = null;
if (beanName == null) {
beanName = getBeanNameForType(beanFactory, handler, requireExistingBean);
Expand All @@ -150,9 +151,10 @@ private void replaceOrCreateBean(ConfigurableListableBeanFactory beanFactory, Be
}
else if (requireExistingBean) {
throw new IllegalStateException("""
Unable to override bean: there is no bean to replace \
with name [%s] and type [%s]."""
.formatted(beanName, handler.getBeanType()));
Unable to replace bean: there is no bean with name '%s' and type %s \
(as required by field '%s.%s')."""
.formatted(beanName, handler.getBeanType(),
field.getDeclaringClass().getSimpleName(), field.getName()));
}
}

Expand All @@ -179,7 +181,7 @@ else if (Boolean.getBoolean(AbstractAotProcessor.AOT_PROCESSING)) {

if (!(beanFactory instanceof BeanDefinitionRegistry registry)) {
throw new IllegalStateException("Cannot process bean override with a BeanFactory " +
"that doesn't implement BeanDefinitionRegistry: " + beanFactory.getClass().getName());
"that does not implement BeanDefinitionRegistry: " + beanFactory.getClass().getName());
}

RootBeanDefinition pseudoBeanDefinition = createPseudoBeanDefinition(handler);
Expand Down Expand Up @@ -220,6 +222,7 @@ else if (Boolean.getBoolean(AbstractAotProcessor.AOT_PROCESSING)) {
*/
private void wrapBean(ConfigurableListableBeanFactory beanFactory, BeanOverrideHandler handler) {
String beanName = handler.getBeanName();
Field field = handler.getField();
ResolvableType beanType = handler.getBeanType();

if (beanName == null) {
Expand All @@ -235,13 +238,17 @@ private void wrapBean(ConfigurableListableBeanFactory beanFactory, BeanOverrideH
beanName = primaryCandidate;
}
else {
Field field = handler.getField();
throw new IllegalStateException("""
Unable to select a bean to override by wrapping: found %d bean instances of type %s \
(as required by annotated field '%s.%s')%s"""
String message = "Unable to select a bean to wrap: ";
if (candidateCount == 0) {
message += "there are no beans of type %s (as required by field '%s.%s')."
.formatted(beanType, field.getDeclaringClass().getSimpleName(), field.getName());
}
else {
message += "found %d beans of type %s (as required by field '%s.%s'): %s"
.formatted(candidateCount, beanType, field.getDeclaringClass().getSimpleName(),
field.getName(), (candidateCount > 0 ? ": " + candidateNames : "")));

field.getName(), candidateNames);
}
throw new IllegalStateException(message);
}
}
beanName = BeanFactoryUtils.transformedBeanName(beanName);
Expand All @@ -251,9 +258,10 @@ private void wrapBean(ConfigurableListableBeanFactory beanFactory, BeanOverrideH
Set<String> candidates = getExistingBeanNamesByType(beanFactory, handler, false);
if (!candidates.contains(beanName)) {
throw new IllegalStateException("""
Unable to override bean by wrapping: there is no existing bean \
with name [%s] and type [%s]."""
.formatted(beanName, beanType));
Unable to wrap bean: there is no bean with name '%s' and type %s \
(as required by field '%s.%s')."""
.formatted(beanName, beanType, field.getDeclaringClass().getSimpleName(),
field.getName()));
}
}

Expand All @@ -276,7 +284,7 @@ private String getBeanNameForType(ConfigurableListableBeanFactory beanFactory, B
else if (candidateCount == 0) {
if (requireExistingBean) {
throw new IllegalStateException(
"Unable to override bean: no beans of type %s (as required by annotated field '%s.%s')"
"Unable to override bean: there are no beans of type %s (as required by field '%s.%s')."
.formatted(beanType, field.getDeclaringClass().getSimpleName(), field.getName()));
}
return null;
Expand All @@ -287,9 +295,8 @@ else if (candidateCount == 0) {
return primaryCandidate;
}

throw new IllegalStateException("""
Unable to select a bean to override: found %s beans of type %s \
(as required by annotated field '%s.%s'): %s"""
throw new IllegalStateException(
"Unable to select a bean to override: found %d beans of type %s (as required by field '%s.%s'): %s"
.formatted(candidateCount, beanType, field.getDeclaringClass().getSimpleName(),
field.getName(), candidateNames));
}
Expand Down Expand Up @@ -416,7 +423,7 @@ private static void validateBeanDefinition(ConfigurableListableBeanFactory beanF
private static void destroySingleton(ConfigurableListableBeanFactory beanFactory, String beanName) {
if (!(beanFactory instanceof DefaultListableBeanFactory dlbf)) {
throw new IllegalStateException("Cannot process bean override with a BeanFactory " +
"that doesn't implement DefaultListableBeanFactory: " + beanFactory.getClass().getName());
"that does not implement DefaultListableBeanFactory: " + beanFactory.getClass().getName());
}
dlbf.destroySingleton(beanName);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.lang.reflect.Field;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
Expand Down Expand Up @@ -84,8 +85,9 @@ void replaceBeanByNameWithoutMatchingBeanDefinitionFails() {

assertThatIllegalStateException()
.isThrownBy(context::refresh)
.withMessage("Unable to override bean: there is no bean " +
"to replace with name [descriptionBean] and type [java.lang.String].");
.withMessage("""
Unable to replace bean: there is no bean with name 'descriptionBean' \
and type java.lang.String (as required by field 'ByNameTestCase.description').""");
}

@Test
Expand All @@ -95,8 +97,9 @@ void replaceBeanByNameWithMatchingBeanDefinitionAndWrongTypeFails() {

assertThatIllegalStateException()
.isThrownBy(context::refresh)
.withMessage("Unable to override bean: there is no bean " +
"to replace with name [descriptionBean] and type [java.lang.String].");
.withMessage("""
Unable to replace bean: there is no bean with name 'descriptionBean' \
and type java.lang.String (as required by field 'ByNameTestCase.description').""");
}

@Test
Expand Down Expand Up @@ -141,8 +144,9 @@ void replaceBeanByTypeWithoutMatchingBeanFails() {

assertThatIllegalStateException()
.isThrownBy(context::refresh)
.withMessage("Unable to override bean: no beans of type java.lang.Integer " +
"(as required by annotated field 'ByTypeTestCase.counter')");
.withMessage("""
Unable to override bean: there are no beans of type java.lang.Integer \
(as required by field 'ByTypeTestCase.counter').""");
}

@Test
Expand All @@ -153,9 +157,10 @@ void replaceBeanByTypeWithMultipleCandidatesAndNoQualifierFails() {

assertThatIllegalStateException()
.isThrownBy(context::refresh)
.withMessage("Unable to select a bean to override: found 2 beans " +
"of type java.lang.Integer (as required by annotated field 'ByTypeTestCase.counter'): " +
"[someInteger, anotherInteger]");
.withMessage("""
Unable to select a bean to override: found 2 beans of type java.lang.Integer \
(as required by field 'ByTypeTestCase.counter'): %s""",
List.of("someInteger", "anotherInteger"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ void cannotOverrideBeanByNameWithNoSuchBeanName() {
assertThatIllegalStateException()
.isThrownBy(context::refresh)
.withMessage("""
Unable to override bean: there is no bean \
to replace with name [beanToOverride] and type [java.lang.String].""");
Unable to replace bean: there is no bean with name 'beanToOverride' \
and type java.lang.String (as required by field 'FailureByNameLookup.example').""");
}

@Test
Expand All @@ -52,8 +52,8 @@ void cannotOverrideBeanByNameWithBeanOfWrongType() {
assertThatIllegalStateException()
.isThrownBy(context::refresh)
.withMessage("""
Unable to override bean: there is no bean \
to replace with name [beanToOverride] and type [java.lang.String].""");
Unable to replace bean: there is no bean with name 'beanToOverride' \
and type java.lang.String (as required by field 'FailureByNameLookup.example').""");
}

@Test
Expand All @@ -63,8 +63,8 @@ void cannotOverrideBeanByTypeWithNoSuchBeanType() {
assertThatIllegalStateException()
.isThrownBy(context::refresh)
.withMessage("""
Unable to override bean: no beans of \
type %s (as required by annotated field '%s.example')""".formatted(
Unable to override bean: there are no beans of \
type %s (as required by field '%s.example').""".formatted(
String.class.getName(), FailureByTypeLookup.class.getSimpleName()));
}

Expand All @@ -77,9 +77,8 @@ void cannotOverrideBeanByTypeWithTooManyBeansOfThatType() {
assertThatIllegalStateException()
.isThrownBy(context::refresh)
.withMessage("""
Unable to select a bean to override: found 2 beans \
of type %s (as required by annotated field '%s.example'): %s""".formatted(
String.class.getName(), FailureByTypeLookup.class.getSimpleName(), List.of("bean1", "bean2")));
Unable to select a bean to override: found 2 beans of type java.lang.String \
(as required by field 'FailureByTypeLookup.example'): %s""", List.of("bean1", "bean2"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ void cannotOverrideBeanByNameWithNoSuchBeanName() {
assertThatIllegalStateException()
.isThrownBy(context::refresh)
.withMessage("""
Unable to override bean: there is no bean \
to replace with name [beanToOverride] and type [java.lang.String].""");
Unable to replace bean: there is no bean with name 'beanToOverride' \
and type java.lang.String (as required by field 'FailureByNameLookup.example').""");
}

@Test
Expand All @@ -53,8 +53,8 @@ void cannotOverrideBeanByNameWithBeanOfWrongType() {
assertThatIllegalStateException()
.isThrownBy(context::refresh)
.withMessage("""
Unable to override bean: there is no bean \
to replace with name [beanToOverride] and type [java.lang.String].""");
Unable to replace bean: there is no bean with name 'beanToOverride' \
and type java.lang.String (as required by field 'FailureByNameLookup.example').""");
}

@Test
Expand All @@ -64,9 +64,8 @@ void cannotOverrideBeanByTypeWithNoSuchBeanType() {
assertThatIllegalStateException()
.isThrownBy(context::refresh)
.withMessage("""
Unable to override bean: no beans of \
type %s (as required by annotated field '%s.example')""".formatted(
String.class.getName(), FailureByTypeLookup.class.getSimpleName()));
Unable to override bean: there are no beans of \
type java.lang.String (as required by field 'FailureByTypeLookup.example').""");
}

@Test
Expand All @@ -78,9 +77,9 @@ void cannotOverrideBeanByTypeWithTooManyBeansOfThatType() {
assertThatIllegalStateException()
.isThrownBy(context::refresh)
.withMessage("""
Unable to select a bean to override: found 2 beans \
of type %s (as required by annotated field '%s.example'): %s""".formatted(
String.class.getName(), FailureByTypeLookup.class.getSimpleName(), List.of("bean1", "bean2")));
Unable to select a bean to override: found 2 beans of type java.lang.String \
(as required by field 'FailureByTypeLookup.example'): %s""",
List.of("bean1", "bean2"));
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,9 @@ void contextCustomizerCannotBeCreatedWithNoSuchBeanName() {
assertThatIllegalStateException()
.isThrownBy(context::refresh)
.withMessage("""
Unable to override bean by wrapping: \
there is no existing bean with name [beanToSpy] and type [%s].""",
String.class.getName());
}
Unable to wrap bean: there is no bean with name 'beanToSpy' and \
type java.lang.String (as required by field 'ByNameSingleLookup.example').""");
}

@Test
void contextCustomizerCannotBeCreatedWithNoSuchBeanType() {
Expand All @@ -52,9 +51,8 @@ void contextCustomizerCannotBeCreatedWithNoSuchBeanType() {
assertThatIllegalStateException()
.isThrownBy(context::refresh)
.withMessage("""
Unable to select a bean to override by wrapping: found 0 bean instances of \
type %s (as required by annotated field '%s.example')""",
String.class.getName(), ByTypeSingleLookup.class.getSimpleName());
Unable to select a bean to wrap: there are no beans of type java.lang.String \
(as required by field 'ByTypeSingleLookup.example').""");
}

@Test
Expand All @@ -66,9 +64,9 @@ void contextCustomizerCannotBeCreatedWithTooManyBeansOfThatType() {
assertThatIllegalStateException()
.isThrownBy(context::refresh)
.withMessage("""
Unable to select a bean to override by wrapping: found 2 bean instances \
of type %s (as required by annotated field '%s.example'): %s""",
String.class.getName(), ByTypeSingleLookup.class.getSimpleName(), List.of("bean1", "bean2"));
Unable to select a bean to wrap: found 2 beans of type java.lang.String \
(as required by field 'ByTypeSingleLookup.example'): %s""",
List.of("bean1", "bean2"));
}


Expand Down

0 comments on commit b9cf03f

Please sign in to comment.