Skip to content

Commit 8bcdb4b

Browse files
committed
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
1 parent 85f6641 commit 8bcdb4b

File tree

3 files changed

+29
-9
lines changed

3 files changed

+29
-9
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataLocationResolvers.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -69,17 +69,17 @@ class ConfigDataLocationResolvers {
6969
@SuppressWarnings("rawtypes")
7070
private List<ConfigDataLocationResolver<?>> reorder(List<ConfigDataLocationResolver> resolvers) {
7171
List<ConfigDataLocationResolver<?>> reordered = new ArrayList<>(resolvers.size());
72-
StandardConfigDataLocationResolver resourceResolver = null;
72+
ConfigDataLocationResolver<?> standardConfigDataLocationResolver = null;
7373
for (ConfigDataLocationResolver<?> resolver : resolvers) {
74-
if (resolver instanceof StandardConfigDataLocationResolver configDataLocationResolver) {
75-
resourceResolver = configDataLocationResolver;
74+
if (resolver instanceof StandardConfigDataLocationResolver) {
75+
standardConfigDataLocationResolver = resolver;
7676
}
7777
else {
7878
reordered.add(resolver);
7979
}
8080
}
81-
if (resourceResolver != null) {
82-
reordered.add(resourceResolver);
81+
if (standardConfigDataLocationResolver != null) {
82+
reordered.add(standardConfigDataLocationResolver);
8383
}
8484
return Collections.unmodifiableList(reordered);
8585
}

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/StandardConfigDataLocationResolver.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.springframework.core.log.LogMessage;
4646
import org.springframework.util.Assert;
4747
import org.springframework.util.ObjectUtils;
48+
import org.springframework.util.ResourceUtils;
4849
import org.springframework.util.StringUtils;
4950

5051
/**
@@ -231,8 +232,17 @@ private Set<StandardConfigDataReference> getReferencesForFile(ConfigDataLocation
231232
if (configDataLocation.isOptional()) {
232233
return Collections.emptySet();
233234
}
234-
throw new IllegalStateException("File extension is not known to any PropertySourceLoader. "
235-
+ "If the location is meant to reference a directory, it must end in '/' or File.separator");
235+
if (configDataLocation.hasPrefix(PREFIX) || configDataLocation.hasPrefix(ResourceUtils.FILE_URL_PREFIX)
236+
|| configDataLocation.hasPrefix(ResourceUtils.CLASSPATH_URL_PREFIX)
237+
|| configDataLocation.toString().indexOf(':') == -1) {
238+
throw new IllegalStateException("File extension is not known to any PropertySourceLoader. "
239+
+ "If the location is meant to reference a directory, it must end in '/' or File.separator");
240+
}
241+
throw new IllegalStateException(
242+
"Incorrect ConfigDataLocationResolver chosen or file extension is not known to any PropertySourceLoader. "
243+
+ "If the location is meant to reference a directory, it must end in '/' or File.separator. "
244+
+ "The location is being resolved using the StandardConfigDataLocationResolver, "
245+
+ "check the location prefix if a different resolver is expected");
236246
}
237247

238248
private String getLoadableFileExtension(PropertySourceLoader loader, String file) {

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/StandardConfigDataLocationResolverTests.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -99,6 +99,16 @@ void resolveWhenLocationIsFileAndNoMatchingLoaderThrowsException() {
9999
.satisfies((ex) -> assertThat(ex.getCause()).hasMessageStartingWith("File extension is not known"));
100100
}
101101

102+
@Test
103+
void resolveWhenLocationHasUnknownPrefixAndNoMatchingLoaderThrowsException() {
104+
ConfigDataLocation location = ConfigDataLocation
105+
.of("typo:src/test/resources/configdata/properties/application.unknown");
106+
assertThatIllegalStateException().isThrownBy(() -> this.resolver.resolve(this.context, location))
107+
.withMessageStartingWith("Unable to load config data from")
108+
.satisfies((ex) -> assertThat(ex.getCause()).hasMessageStartingWith(
109+
"Incorrect ConfigDataLocationResolver chosen or file extension is not known to any PropertySourceLoader"));
110+
}
111+
102112
@Test
103113
void resolveWhenLocationWildcardIsSpecifiedForClasspathLocationThrowsException() {
104114
ConfigDataLocation location = ConfigDataLocation.of("classpath*:application.properties");

0 commit comments

Comments
 (0)