Skip to content

Commit 6f9f3e5

Browse files
authored
Improve error message in case of invalid dynamic templates (#60870)
Include the attempted 'match_mapping_type' into the message, so that it is clearer that multiple validation attempts have occurred. Dynamic template validation was recently added via #51233 and there was some confusion over the deprecation message itself. (in 7.x only deprecation warning will be omitted and from 8.0 an error will be returned)
1 parent 1f8d1e9 commit 6f9f3e5

File tree

3 files changed

+16
-11
lines changed

3 files changed

+16
-11
lines changed

docs/reference/mapping/dynamic/templates.asciidoc

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,16 @@ Dynamic templates are specified as an array of named objects:
3838
<3> The mapping that the matched field should use.
3939

4040
If a provided mapping contains an invalid mapping snippet, a validation error
41-
is returned. Validation occurs when applying the dynamic template at index time,
42-
and, in most cases, when the dynamic template is updated. Providing an invalid mapping
41+
is returned. Validation occurs when applying the dynamic template at index time,
42+
and, in most cases, when the dynamic template is updated. Providing an invalid mapping
4343
snippet may cause the update or validation of a dynamic template to fail under certain conditions:
4444

45-
* If no `match_mapping_type` has been specified but the template is valid for at least one predefined mapping type,
46-
the mapping snippet is considered valid. However, a validation error is returned at index time if a field matching
47-
the template is indexed as a different type. For example, configuring a dynamic template with no `match_mapping_type`
48-
is considered valid as string type, but if a field matching the dynamic template is indexed as a long, a validation
49-
error is returned at index time.
45+
* If no `match_mapping_type` has been specified but the template is valid for at least one predefined mapping type,
46+
the mapping snippet is considered valid. However, a validation error is returned at index time if a field matching
47+
the template is indexed as a different type. For example, configuring a dynamic template with no `match_mapping_type`
48+
is considered valid as string type, but if a field matching the dynamic template is indexed as a long, a validation
49+
error is returned at index time. It is recommended to configure the `match_mapping_type` to the expected JSON type or
50+
configure the desired `type` in the mapping snippet.
5051

5152
* If the `{name}` placeholder is used in the mapping snippet, validation is skipped when updating the dynamic
5253
template. This is because the field name is unknown at that time. Instead, validation occurs when the template is applied

server/src/main/java/org/elasticsearch/index/mapper/RootObjectMapper.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
import java.io.IOException;
3333
import java.util.ArrayList;
34+
import java.util.Arrays;
3435
import java.util.Collection;
3536
import java.util.Collections;
3637
import java.util.Iterator;
@@ -408,14 +409,16 @@ private static void validateDynamicTemplate(Mapper.TypeParser.ParserContext pars
408409

409410
final boolean failInvalidDynamicTemplates = parserContext.indexVersionCreated().onOrAfter(Version.V_8_0_0);
410411
if (dynamicTemplateInvalid) {
411-
String message = String.format(Locale.ROOT, "dynamic template [%s] has invalid content [%s]",
412-
dynamicTemplate.getName(), Strings.toString(dynamicTemplate));
412+
String format = "dynamic template [%s] has invalid content [%s], " +
413+
"attempted to validate it with the following match_mapping_type: [%s]";
414+
String message = String.format(Locale.ROOT, format, dynamicTemplate.getName(), Strings.toString(dynamicTemplate),
415+
Arrays.toString(types));
413416
if (failInvalidDynamicTemplates) {
414417
throw new IllegalArgumentException(message, lastError);
415418
} else {
416419
final String deprecationMessage;
417420
if (lastError != null) {
418-
deprecationMessage = String.format(Locale.ROOT, "%s, caused by [%s]", message, lastError.getMessage());
421+
deprecationMessage = String.format(Locale.ROOT, "%s, last error: [%s]", message, lastError.getMessage());
419422
} else {
420423
deprecationMessage = message;
421424
}

server/src/test/java/org/elasticsearch/index/mapper/RootObjectMapperTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ public void testIllegalDynamicTemplate7DotXIndex() throws Exception {
472472
DocumentMapper mapper = mapperService.merge("type", new CompressedXContent(Strings.toString(mapping)), MergeReason.MAPPING_UPDATE);
473473
assertThat(mapper.mappingSource().toString(), containsString("\"type\":\"string\""));
474474
assertWarnings("dynamic template [my_template] has invalid content [{\"match_mapping_type\":\"string\",\"mapping\":{\"type\":" +
475-
"\"string\"}}], caused by [No mapper found for type [string]]");
475+
"\"string\"}}], attempted to validate it with the following match_mapping_type: [[string]], " +
476+
"last error: [No mapper found for type [string]]");
476477
}
477478
}

0 commit comments

Comments
 (0)