From 7446f75346576dc816a8147699f1f43122839423 Mon Sep 17 00:00:00 2001 From: Igor Motov Date: Thu, 13 Dec 2018 17:32:45 +0400 Subject: [PATCH] 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 --- .../index/mapper/GeoPointFieldMapper.java | 84 ++++++++++--------- .../mapper/GeoPointFieldMapperTests.java | 2 +- 2 files changed, 45 insertions(+), 41 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java index 2880169edb5..1621f60b9b7 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java +++ b/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); - } - parse(context, sparse.reset(lat, lon)); - } else { + 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) { - if (token == XContentParser.Token.VALUE_STRING) { - parseGeoPointStringIgnoringMalformed(context, sparse); - } else { - parseGeoPointIgnoringMalformed(context, sparse); - } + 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); + } + 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(); diff --git a/server/src/test/java/org/elasticsearch/index/mapper/GeoPointFieldMapperTests.java b/server/src/test/java/org/elasticsearch/index/mapper/GeoPointFieldMapperTests.java index 1725f079e0e..a2c17e68b78 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/GeoPointFieldMapperTests.java +++ b/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]")); }