浏览代码

Add matching pattern to error in fields (#76903)

This adds the pattern into the error message returned when trying to
fetch fields. So this:
```
POST _search {
  "fields": [ { "field": "*", "format": "date_time" } ]
}
```

Will return an error message like
```
error fetching [foo] which matches [*]: Field [foo] of type [keyword] doesn't support formats
```
Nik Everett 4 年之前
父节点
当前提交
dde7d418a8

+ 115 - 0
rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/330_fetch_fields.yml

@@ -855,6 +855,7 @@ Test nested field with sibling field resolving to DocValueFetcher:
   - match: { hits.hits.0.fields.number.2 : 3 }
   - match: { hits.hits.0.fields.number.3 : 5 }
   - match: { hits.hits.0.fields.number.4 : 6 }
+
 ---
 Test token_count inside nested field doesn't fail:
   - skip:
@@ -892,3 +893,117 @@ Test token_count inside nested field doesn't fail:
            body:
               _source: false
               fields: [ "*" ]
+
+---
+error includes field name:
+  - skip:
+      version: ' - 7.99.99'
+      reason:  'error changed in 8.0.0 to be backported to 7.15'
+
+  - do:
+      indices.create:
+        index:  test
+        body:
+          settings:
+            index.number_of_shards: 1
+          mappings:
+            properties:
+              keyword:
+                type: keyword
+              date:
+                type: date
+
+  - do:
+      index:
+        index:   test
+        id:      1
+        refresh: true
+        body:
+          keyword: "value"
+          date: "1990-12-29T22:30:00.000Z"
+
+  - do:
+      catch: '/error fetching \[keyword\]: Field \[keyword\] of type \[keyword\] doesn''t support formats./'
+      search:
+        index: test
+        body:
+          fields:
+            - field: keyword
+              format: "yyyy/MM/dd"
+
+---
+error includes glob pattern:
+  - skip:
+      version: ' - 7.99.99'
+      reason:  'error changed in 8.0.0 to be backported to 7.15'
+
+  - do:
+      indices.create:
+        index:  test
+        body:
+          settings:
+            index.number_of_shards: 1
+          mappings:
+            properties:
+              dkeyword:
+                type: keyword
+              date:
+                type: date
+
+  - do:
+      index:
+        index:   test
+        id:      1
+        refresh: true
+        body:
+          dkeyword: "value"
+          date: "1990-12-29T22:30:00.000Z"
+
+  - do:
+      catch: '/error fetching \[dkeyword\] which matched \[d\*\]: Field \[dkeyword\] of type \[keyword\] doesn''t support formats./'
+      search:
+        index: test
+        body:
+          fields:
+            - field: d*
+              format: "yyyy/MM/dd"
+
+
+---
+error for flattened includes whole path:
+  - skip:
+      version: ' - 7.99.99'
+      reason:  'error changed in 8.0.0 to be backported to 7.15'
+
+  - do:
+      indices.create:
+        index:  test
+        body:
+          settings:
+            index.number_of_shards: 1
+          mappings:
+            properties:
+              flattened:
+                type: flattened
+
+              date:
+                type: date
+
+  - do:
+      index:
+        index:   test
+        id:      1
+        refresh: true
+        body:
+          flattened:
+            foo: bar
+          date: "1990-12-29T22:30:00.000Z"
+
+  - do:
+      catch: '/error fetching \[flattened.bar\]: Field \[flattened.bar\] of type \[flattened\] doesn''t support formats./'
+      search:
+        index: test
+        body:
+          fields:
+            - field: flattened.bar
+              format: "yyyy/MM/dd"

+ 11 - 1
server/src/main/java/org/elasticsearch/search/fetch/subphase/FieldFetcher.java

@@ -92,7 +92,17 @@ public class FieldFetcher {
                 }
                 // only add concrete fields if they are not beneath a known nested field
                 if (nestedParentPath == null) {
-                    ValueFetcher valueFetcher = ft.valueFetcher(context, fieldAndFormat.format);
+                    ValueFetcher valueFetcher;
+                    try {
+                        valueFetcher = ft.valueFetcher(context, fieldAndFormat.format);
+                    } catch (IllegalArgumentException e) {
+                        StringBuilder error = new StringBuilder("error fetching [").append(field).append(']');
+                        if (isWildcardPattern) {
+                            error.append(" which matched [").append(fieldAndFormat.field).append(']');
+                        }
+                        error.append(": ").append(e.getMessage());
+                        throw new IllegalArgumentException(error.toString(), e);
+                    }
                     fieldContexts.put(field, new FieldContext(field, valueFetcher));
                 }
             }

+ 3 - 0
x-pack/qa/runtime-fields/build.gradle

@@ -80,6 +80,9 @@ subprojects {
           'search.aggregation/20_terms/Global ordinals are loaded with the global_ordinals execution hint',
           'search.aggregation/170_cardinality_metric/profiler string',
           'search.aggregation/235_composite_sorted/*',
+          // The error messages are different
+          'search/330_fetch_fields/error includes field name',
+          'search/330_fetch_fields/error includes glob pattern',
           /////// NOT SUPPORTED ///////
         ].join(',')
     }