فهرست منبع

Improve error message when index settings are not a map (#45588)

This commit adds an explicit error message when a create index request
contains a settings key that is not a json object. Prior to this change
the user would be given a ClassCastException with no explanation of what
went wrong.

closes #45126
Ryan Ernst 6 سال پیش
والد
کامیت
609a8048d9

+ 3 - 0
server/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java

@@ -386,6 +386,9 @@ public class CreateIndexRequest extends AcknowledgedRequest<CreateIndexRequest>
         for (Map.Entry<String, ?> entry : source.entrySet()) {
             String name = entry.getKey();
             if (SETTINGS.match(name, deprecationHandler)) {
+                if (entry.getValue() instanceof Map == false) {
+                    throw new ElasticsearchParseException("key [settings] must be an object");
+                }
                 settings((Map<String, Object>) entry.getValue());
             } else if (MAPPINGS.match(name, deprecationHandler)) {
                 Map<String, Object> mappings = (Map<String, Object>) entry.getValue();

+ 10 - 0
server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequestTests.java

@@ -44,6 +44,7 @@ import java.util.Set;
 
 import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_SHARDS;
 import static org.elasticsearch.common.xcontent.ToXContent.EMPTY_PARAMS;
+import static org.hamcrest.CoreMatchers.equalTo;
 
 public class CreateIndexRequestTests extends ESTestCase {
 
@@ -196,6 +197,15 @@ public class CreateIndexRequestTests extends ESTestCase {
         ElasticsearchAssertions.assertToXContentEquivalent(originalBytes, finalBytes, xContentType);
     }
 
+    public void testSettingsType() throws IOException {
+        XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values()));
+        builder.startObject().startArray("settings").endArray().endObject();
+
+        CreateIndexRequest parsedCreateIndexRequest = new CreateIndexRequest();
+        ElasticsearchParseException e = expectThrows(ElasticsearchParseException.class, () -> parsedCreateIndexRequest.source(builder));
+        assertThat(e.getMessage(), equalTo("key [settings] must be an object"));
+    }
+
     public static void assertMappingsEqual(Map<String, String> expected, Map<String, String> actual) throws IOException {
         assertEquals(expected.keySet(), actual.keySet());