Improve error message when spring.config.import fails to resolve
Update `StandardConfigDataLocationResolver` to give a better error message when a location cannot be resolved. Prior to this commit, a location with a misspelling in the prefix would only give an error about the file extension being not known. Fixes gh-36243
This commit is contained in:
parent
85f6641a7e
commit
8bcdb4b06b
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2023 the original author or authors.
|
* Copyright 2012-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -69,17 +69,17 @@ class ConfigDataLocationResolvers {
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
private List<ConfigDataLocationResolver<?>> reorder(List<ConfigDataLocationResolver> resolvers) {
|
private List<ConfigDataLocationResolver<?>> reorder(List<ConfigDataLocationResolver> resolvers) {
|
||||||
List<ConfigDataLocationResolver<?>> reordered = new ArrayList<>(resolvers.size());
|
List<ConfigDataLocationResolver<?>> reordered = new ArrayList<>(resolvers.size());
|
||||||
StandardConfigDataLocationResolver resourceResolver = null;
|
ConfigDataLocationResolver<?> standardConfigDataLocationResolver = null;
|
||||||
for (ConfigDataLocationResolver<?> resolver : resolvers) {
|
for (ConfigDataLocationResolver<?> resolver : resolvers) {
|
||||||
if (resolver instanceof StandardConfigDataLocationResolver configDataLocationResolver) {
|
if (resolver instanceof StandardConfigDataLocationResolver) {
|
||||||
resourceResolver = configDataLocationResolver;
|
standardConfigDataLocationResolver = resolver;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
reordered.add(resolver);
|
reordered.add(resolver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (resourceResolver != null) {
|
if (standardConfigDataLocationResolver != null) {
|
||||||
reordered.add(resourceResolver);
|
reordered.add(standardConfigDataLocationResolver);
|
||||||
}
|
}
|
||||||
return Collections.unmodifiableList(reordered);
|
return Collections.unmodifiableList(reordered);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||||
import org.springframework.core.log.LogMessage;
|
import org.springframework.core.log.LogMessage;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
import org.springframework.util.ResourceUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -231,9 +232,18 @@ public class StandardConfigDataLocationResolver
|
||||||
if (configDataLocation.isOptional()) {
|
if (configDataLocation.isOptional()) {
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
if (configDataLocation.hasPrefix(PREFIX) || configDataLocation.hasPrefix(ResourceUtils.FILE_URL_PREFIX)
|
||||||
|
|| configDataLocation.hasPrefix(ResourceUtils.CLASSPATH_URL_PREFIX)
|
||||||
|
|| configDataLocation.toString().indexOf(':') == -1) {
|
||||||
throw new IllegalStateException("File extension is not known to any PropertySourceLoader. "
|
throw new IllegalStateException("File extension is not known to any PropertySourceLoader. "
|
||||||
+ "If the location is meant to reference a directory, it must end in '/' or File.separator");
|
+ "If the location is meant to reference a directory, it must end in '/' or File.separator");
|
||||||
}
|
}
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Incorrect ConfigDataLocationResolver chosen or file extension is not known to any PropertySourceLoader. "
|
||||||
|
+ "If the location is meant to reference a directory, it must end in '/' or File.separator. "
|
||||||
|
+ "The location is being resolved using the StandardConfigDataLocationResolver, "
|
||||||
|
+ "check the location prefix if a different resolver is expected");
|
||||||
|
}
|
||||||
|
|
||||||
private String getLoadableFileExtension(PropertySourceLoader loader, String file) {
|
private String getLoadableFileExtension(PropertySourceLoader loader, String file) {
|
||||||
for (String fileExtension : loader.getFileExtensions()) {
|
for (String fileExtension : loader.getFileExtensions()) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2023 the original author or authors.
|
* Copyright 2012-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -99,6 +99,16 @@ class StandardConfigDataLocationResolverTests {
|
||||||
.satisfies((ex) -> assertThat(ex.getCause()).hasMessageStartingWith("File extension is not known"));
|
.satisfies((ex) -> assertThat(ex.getCause()).hasMessageStartingWith("File extension is not known"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void resolveWhenLocationHasUnknownPrefixAndNoMatchingLoaderThrowsException() {
|
||||||
|
ConfigDataLocation location = ConfigDataLocation
|
||||||
|
.of("typo:src/test/resources/configdata/properties/application.unknown");
|
||||||
|
assertThatIllegalStateException().isThrownBy(() -> this.resolver.resolve(this.context, location))
|
||||||
|
.withMessageStartingWith("Unable to load config data from")
|
||||||
|
.satisfies((ex) -> assertThat(ex.getCause()).hasMessageStartingWith(
|
||||||
|
"Incorrect ConfigDataLocationResolver chosen or file extension is not known to any PropertySourceLoader"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void resolveWhenLocationWildcardIsSpecifiedForClasspathLocationThrowsException() {
|
void resolveWhenLocationWildcardIsSpecifiedForClasspathLocationThrowsException() {
|
||||||
ConfigDataLocation location = ConfigDataLocation.of("classpath*:application.properties");
|
ConfigDataLocation location = ConfigDataLocation.of("classpath*:application.properties");
|
||||||
|
|
Loading…
Reference in New Issue