Provide dedicated AOT exception hierarchy

This commit adds a number of catch point that provides additional
context when an AOT processor fails to execute. Amongst other things,
this makes sure that the bean name and its descriptor is consistently
provided in the error message when available.

Closes gh-32777
This commit is contained in:
Stéphane Nicoll
2024-06-03 15:45:15 +02:00
parent f31113e325
commit 42ace2c2c9
13 changed files with 294 additions and 33 deletions

View File

@@ -40,6 +40,7 @@ import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
import org.springframework.aot.test.generate.TestGenerationContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.aot.AotProcessingException;
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotContribution;
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor;
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
@@ -94,6 +95,7 @@ import org.springframework.mock.env.MockEnvironment;
import org.springframework.util.ReflectionUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Tests for {@link ApplicationContextAotGenerator}.
@@ -587,6 +589,22 @@ class ApplicationContextAotGeneratorTests {
}
@Nested
class ExceptionHanding {
@Test
void failureProcessingBeanFactoryAotContribution() {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBeanDefinition("test",
new RootBeanDefinition(FailingBeanFactoryInitializationAotContribution.class));
assertThatExceptionOfType(AotProcessingException.class)
.isThrownBy(() -> processAheadOfTime(applicationContext))
.withMessageStartingWith("Error executing '")
.withMessageContaining(FailingBeanFactoryInitializationAotContribution.class.getName())
.withMessageContaining("Test exception");
}
}
private static void registerBeanPostProcessor(GenericApplicationContext applicationContext,
String beanName, Class<?> beanPostProcessorClass) {
@@ -676,4 +694,12 @@ class ApplicationContextAotGeneratorTests {
}
static class FailingBeanFactoryInitializationAotContribution implements BeanFactoryInitializationAotProcessor {
@Override
public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) {
throw new IllegalStateException("Test exception");
}
}
}

View File

@@ -31,6 +31,7 @@ import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.test.generate.TestGenerationContext;
import org.springframework.beans.BeanInstantiationException;
import org.springframework.beans.factory.aot.AotProcessingException;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
@@ -40,7 +41,7 @@ import org.springframework.context.support.GenericApplicationContext;
import org.springframework.lang.Nullable;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Tests for {@link RuntimeHintsBeanFactoryInitializationAotProcessor}.
@@ -119,9 +120,9 @@ class RuntimeHintsBeanFactoryInitializationAotProcessorTests {
void shouldRejectRuntimeHintsRegistrarWithoutDefaultConstructor() {
GenericApplicationContext applicationContext = createApplicationContext(
ConfigurationWithIllegalRegistrar.class);
assertThatThrownBy(() -> this.generator.processAheadOfTime(
applicationContext, this.generationContext))
.isInstanceOf(BeanInstantiationException.class);
assertThatExceptionOfType(AotProcessingException.class)
.isThrownBy(() -> this.generator.processAheadOfTime(applicationContext, this.generationContext))
.havingCause().isInstanceOf(BeanInstantiationException.class);
}
private void assertThatSampleRegistrarContributed() {