GH-160 - Polishing.
Moved the message population for the failure analyzer to the exception to be able to give more actionable feedback and educated users on the cause of the problem.
This commit is contained in:
@@ -16,22 +16,29 @@
|
||||
package org.springframework.modulith.runtime.autoconfigure;
|
||||
|
||||
/**
|
||||
* An Exception carrying information about a missing runtime dependency to be
|
||||
* analyzed by {@link MissingRuntimeDependencyFailureAnalyzer}.
|
||||
* An Exception carrying information about a missing runtime dependency to be analyzed by
|
||||
* {@link MissingRuntimeDependencyFailureAnalyzer}.
|
||||
*
|
||||
* @author Michael Weirauch
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
class MissingRuntimeDependencyException extends RuntimeException {
|
||||
class MissingRuntimeDependency extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final String dependencyName;
|
||||
private final String description, suggestedAction;
|
||||
|
||||
public MissingRuntimeDependencyException(String dependencyName) {
|
||||
this.dependencyName = dependencyName;
|
||||
MissingRuntimeDependency(String description, String suggestedAction) {
|
||||
|
||||
this.description = description;
|
||||
this.suggestedAction = suggestedAction;
|
||||
}
|
||||
|
||||
public String getDependencyName() {
|
||||
return dependencyName;
|
||||
String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
String getSuggestedAction() {
|
||||
return suggestedAction;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,17 +20,19 @@ import org.springframework.boot.diagnostics.FailureAnalysis;
|
||||
import org.springframework.boot.diagnostics.FailureAnalyzer;
|
||||
|
||||
/**
|
||||
* {@link FailureAnalyzer} for {@link MissingRuntimeDependencyException}.
|
||||
* {@link FailureAnalyzer} for {@link MissingRuntimeDependency}.
|
||||
*
|
||||
* @author Michael Weirauch
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
class MissingRuntimeDependencyFailureAnalyzer extends AbstractFailureAnalyzer<MissingRuntimeDependencyException> {
|
||||
class MissingRuntimeDependencyFailureAnalyzer extends AbstractFailureAnalyzer<MissingRuntimeDependency> {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.boot.diagnostics.AbstractFailureAnalyzer#analyze(java.lang.Throwable, java.lang.Throwable)
|
||||
*/
|
||||
@Override
|
||||
protected FailureAnalysis analyze(Throwable rootFailure, MissingRuntimeDependencyException cause) {
|
||||
return new FailureAnalysis(
|
||||
String.format("Spring Modulith requires the dependency '%s' to be on the runtime classpath.",
|
||||
cause.getDependencyName()),
|
||||
"Add the missing dependency to the runtime classpath of your project.", cause);
|
||||
protected FailureAnalysis analyze(Throwable rootFailure, MissingRuntimeDependency cause) {
|
||||
return new FailureAnalysis(cause.getDescription(), cause.getSuggestedAction(), cause);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,20 +46,10 @@ import org.springframework.util.Assert;
|
||||
* Bean.
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
* @author Michael Weirauch
|
||||
*/
|
||||
@AutoConfiguration
|
||||
class SpringModulithRuntimeAutoConfiguration {
|
||||
|
||||
@AutoConfiguration
|
||||
@ConditionalOnMissingClass("com.tngtech.archunit.core.importer.ClassFileImporter")
|
||||
static class ArchUnitRuntimeDependencyMissingConfiguration {
|
||||
|
||||
ArchUnitRuntimeDependencyMissingConfiguration() {
|
||||
throw new MissingRuntimeDependencyException("archunit");
|
||||
}
|
||||
}
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SpringModulithRuntimeAutoConfiguration.class);
|
||||
private final AsyncTaskExecutor executor = new SimpleAsyncTaskExecutor();
|
||||
|
||||
@@ -179,4 +169,22 @@ class SpringModulithRuntimeAutoConfiguration {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto-configuration to react to ArchUnit missing on the runtime classpath.
|
||||
*
|
||||
* @author Michael Weirauch
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ConditionalOnMissingClass("com.tngtech.archunit.core.importer.ClassFileImporter")
|
||||
static class ArchUnitRuntimeDependencyMissingConfiguration {
|
||||
|
||||
private static final String DESCRIPTION = "The Spring Modulith runtime support requires ArchUnit to be on the runtime classpath. This might be caused by it declared as test scope dependency, as it usually is used in tests only.";
|
||||
private static final String SUGGESTED_ACTION = "Add ArchUnit to your project and ensure it configured to live in the runtime classpath at least.";
|
||||
|
||||
ArchUnitRuntimeDependencyMissingConfiguration() {
|
||||
throw new MissingRuntimeDependency(DESCRIPTION, SUGGESTED_ACTION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ class SpringModulithRuntimeAutoConfigurationIntegrationTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-160
|
||||
void missingArchUnitRuntimeDependencyEscalatesOnContextStartup() {
|
||||
|
||||
new ApplicationContextRunner()
|
||||
@@ -65,8 +65,8 @@ class SpringModulithRuntimeAutoConfigurationIntegrationTests {
|
||||
|
||||
assertThat(context).hasFailed();
|
||||
assertThat(context.getStartupFailure().getCause())
|
||||
.isInstanceOf(BeanInstantiationException.class)
|
||||
.cause().isInstanceOf(MissingRuntimeDependencyException.class);
|
||||
.isInstanceOf(BeanInstantiationException.class)
|
||||
.cause().isInstanceOf(MissingRuntimeDependency.class);
|
||||
|
||||
context.close();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user