Special case for YAML ParseException caused by bad document boundary
YAML documents can be text literals, so some common typos can be misleading and not generate the expected exception (Boot fails to cast the document to a Map, rather than reporting the underlying exception). Fixes gh-235
This commit is contained in:
@@ -167,6 +167,11 @@ public class YamlProcessor {
|
|||||||
private Map<String, Object> asMap(Object object) {
|
private Map<String, Object> asMap(Object object) {
|
||||||
// YAML can have numbers as keys
|
// YAML can have numbers as keys
|
||||||
Map<String, Object> result = new LinkedHashMap<String, Object>();
|
Map<String, Object> result = new LinkedHashMap<String, Object>();
|
||||||
|
if (!(object instanceof Map)) {
|
||||||
|
// A document can be a text literal
|
||||||
|
result.put("document", object);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
Map<Object, Object> map = (Map<Object, Object>) object;
|
Map<Object, Object> map = (Map<Object, Object>) object;
|
||||||
for (Entry<Object, Object> entry : map.entrySet()) {
|
for (Entry<Object, Object> entry : map.entrySet()) {
|
||||||
Object value = entry.getValue();
|
Object value = entry.getValue();
|
||||||
|
|||||||
@@ -328,21 +328,22 @@ public class ConfigFileApplicationListener implements
|
|||||||
|
|
||||||
private PropertySource<?> getPropertySource(String name, Resource resource,
|
private PropertySource<?> getPropertySource(String name, Resource resource,
|
||||||
String profile, List<PropertySourceLoader> loaders) {
|
String profile, List<PropertySourceLoader> loaders) {
|
||||||
|
if (resource == null || !resource.exists()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
String key = resource.getDescription() + (profile == null ? "" : "#" + profile);
|
String key = resource.getDescription() + (profile == null ? "" : "#" + profile);
|
||||||
if (this.cached.containsKey(key)) {
|
if (this.cached.containsKey(key)) {
|
||||||
return this.cached.get(key);
|
return this.cached.get(key);
|
||||||
}
|
}
|
||||||
boolean satisfied = true;
|
boolean satisfied = true;
|
||||||
for (PropertySourceLoader loader : loaders) {
|
for (PropertySourceLoader loader : loaders) {
|
||||||
if (resource != null && resource.exists()) {
|
if (loader.supports(resource)) {
|
||||||
if (loader.supports(resource)) {
|
PropertySource<?> propertySource = loader.load(name, resource);
|
||||||
PropertySource<?> propertySource = loader.load(name, resource);
|
this.cached.put(key, propertySource);
|
||||||
this.cached.put(key, propertySource);
|
return propertySource;
|
||||||
return propertySource;
|
}
|
||||||
}
|
else {
|
||||||
else {
|
satisfied = false;
|
||||||
satisfied = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!satisfied) {
|
if (!satisfied) {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import org.junit.rules.ExpectedException;
|
|||||||
import org.springframework.boot.config.YamlProcessor.MatchCallback;
|
import org.springframework.boot.config.YamlProcessor.MatchCallback;
|
||||||
import org.springframework.core.io.ByteArrayResource;
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.yaml.snakeyaml.parser.ParserException;
|
||||||
import org.yaml.snakeyaml.scanner.ScannerException;
|
import org.yaml.snakeyaml.scanner.ScannerException;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
@@ -55,6 +56,31 @@ public class YamlProcessorTests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStringResource() throws Exception {
|
||||||
|
this.processor.setResources(new Resource[] { new ByteArrayResource(
|
||||||
|
"foo # a document that is a literal".getBytes()) });
|
||||||
|
this.processor.process(new MatchCallback() {
|
||||||
|
@Override
|
||||||
|
public void process(Properties properties, Map<String, Object> map) {
|
||||||
|
assertEquals("foo", map.get("document"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBadDocumentStart() throws Exception {
|
||||||
|
this.processor.setResources(new Resource[] { new ByteArrayResource(
|
||||||
|
"foo # a document\nbar: baz".getBytes()) });
|
||||||
|
this.exception.expect(ParserException.class);
|
||||||
|
this.exception.expectMessage("line 2, column 1");
|
||||||
|
this.processor.process(new MatchCallback() {
|
||||||
|
@Override
|
||||||
|
public void process(Properties properties, Map<String, Object> map) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBadResource() throws Exception {
|
public void testBadResource() throws Exception {
|
||||||
this.processor.setResources(new Resource[] { new ByteArrayResource(
|
this.processor.setResources(new Resource[] { new ByteArrayResource(
|
||||||
|
|||||||
Reference in New Issue
Block a user