소스 검색

Geo: Adds a name of the field to geopoint parsing errors (#36529)

Adds the field name and type to geo_point parsing errors.

Closes #15965
Igor Motov 6 년 전
부모
커밋
7446f75346

+ 43 - 39
server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java

@@ -291,54 +291,58 @@ public class GeoPointFieldMapper extends FieldMapper implements ArrayValueMapper
     public void parse(ParseContext context) throws IOException {
         context.path().add(simpleName());
 
-        GeoPoint sparse = context.parseExternalValue(GeoPoint.class);
+        try {
+            GeoPoint sparse = context.parseExternalValue(GeoPoint.class);
 
-        if (sparse != null) {
-            parse(context, sparse);
-        } else {
-            sparse = new GeoPoint();
-            XContentParser.Token token = context.parser().currentToken();
-            if (token == XContentParser.Token.START_ARRAY) {
-                token = context.parser().nextToken();
+            if (sparse != null) {
+                parse(context, sparse);
+            } else {
+                sparse = new GeoPoint();
+                XContentParser.Token token = context.parser().currentToken();
                 if (token == XContentParser.Token.START_ARRAY) {
-                    // its an array of array of lon/lat [ [1.2, 1.3], [1.4, 1.5] ]
-                    while (token != XContentParser.Token.END_ARRAY) {
-                        parseGeoPointIgnoringMalformed(context, sparse);
-                        token = context.parser().nextToken();
-                    }
-                } else {
-                    // its an array of other possible values
-                    if (token == XContentParser.Token.VALUE_NUMBER) {
-                        double lon = context.parser().doubleValue();
-                        context.parser().nextToken();
-                        double lat = context.parser().doubleValue();
-                        token = context.parser().nextToken();
-                        if (token == XContentParser.Token.VALUE_NUMBER) {
-                            GeoPoint.assertZValue(ignoreZValue.value(), context.parser().doubleValue());
-                        } else if (token != XContentParser.Token.END_ARRAY) {
-                            throw new ElasticsearchParseException("[{}] field type does not accept > 3 dimensions", CONTENT_TYPE);
+                    token = context.parser().nextToken();
+                    if (token == XContentParser.Token.START_ARRAY) {
+                        // its an array of array of lon/lat [ [1.2, 1.3], [1.4, 1.5] ]
+                        while (token != XContentParser.Token.END_ARRAY) {
+                            parseGeoPointIgnoringMalformed(context, sparse);
+                            token = context.parser().nextToken();
                         }
-                        parse(context, sparse.reset(lat, lon));
                     } else {
-                        while (token != XContentParser.Token.END_ARRAY) {
-                            if (token == XContentParser.Token.VALUE_STRING) {
-                                parseGeoPointStringIgnoringMalformed(context, sparse);
-                            } else {
-                                parseGeoPointIgnoringMalformed(context, sparse);
-                            }
+                        // its an array of other possible values
+                        if (token == XContentParser.Token.VALUE_NUMBER) {
+                            double lon = context.parser().doubleValue();
+                            context.parser().nextToken();
+                            double lat = context.parser().doubleValue();
                             token = context.parser().nextToken();
+                            if (token == XContentParser.Token.VALUE_NUMBER) {
+                                GeoPoint.assertZValue(ignoreZValue.value(), context.parser().doubleValue());
+                            } else if (token != XContentParser.Token.END_ARRAY) {
+                                throw new ElasticsearchParseException("[{}] field type does not accept > 3 dimensions", CONTENT_TYPE);
+                            }
+                            parse(context, sparse.reset(lat, lon));
+                        } else {
+                            while (token != XContentParser.Token.END_ARRAY) {
+                                if (token == XContentParser.Token.VALUE_STRING) {
+                                    parseGeoPointStringIgnoringMalformed(context, sparse);
+                                } else {
+                                    parseGeoPointIgnoringMalformed(context, sparse);
+                                }
+                                token = context.parser().nextToken();
+                            }
                         }
                     }
+                } else if (token == XContentParser.Token.VALUE_STRING) {
+                    parseGeoPointStringIgnoringMalformed(context, sparse);
+                } else if (token == XContentParser.Token.VALUE_NULL) {
+                    if (fieldType.nullValue() != null) {
+                        parse(context, (GeoPoint) fieldType.nullValue());
+                    }
+                } else {
+                    parseGeoPointIgnoringMalformed(context, sparse);
                 }
-            } else if (token == XContentParser.Token.VALUE_STRING) {
-                parseGeoPointStringIgnoringMalformed(context, sparse);
-            } else if (token == XContentParser.Token.VALUE_NULL) {
-                if (fieldType.nullValue() != null) {
-                    parse(context, (GeoPoint) fieldType.nullValue());
-                }
-            } else {
-                 parseGeoPointIgnoringMalformed(context, sparse);
             }
+        } catch (Exception ex) {
+            throw new MapperParsingException("failed to parse field [{}] of type [{}]", ex, fieldType().name(), fieldType().typeName());
         }
 
         context.path().remove();

+ 1 - 1
server/src/test/java/org/elasticsearch/index/mapper/GeoPointFieldMapperTests.java

@@ -452,7 +452,7 @@ public class GeoPointFieldMapperTests extends ESSingleNodeTestCase {
                     .endObject()),
             XContentType.JSON)));
 
-        assertThat(ex.getMessage(), equalTo("failed to parse"));
+        assertThat(ex.getMessage(), equalTo("failed to parse field [location] of type [geo_point]"));
         assertThat(ex.getRootCause().getMessage(), equalTo("unsupported symbol [.] in geohash [1234.333]"));
     }