Enhanced lat/long error handling
NumberFormatExceptions caused by non-double lat/long values are now handled when the ignore_malformed flag is set to true. Closes #16833
This commit is contained in:
parent
20b398daea
commit
3651854bf6
|
@ -374,6 +374,7 @@ public class GeoUtils {
|
|||
double lat = Double.NaN;
|
||||
double lon = Double.NaN;
|
||||
String geohash = null;
|
||||
NumberFormatException numberFormatException = null;
|
||||
|
||||
if(parser.currentToken() == Token.START_OBJECT) {
|
||||
while(parser.nextToken() != Token.END_OBJECT) {
|
||||
|
@ -384,7 +385,11 @@ public class GeoUtils {
|
|||
switch (parser.currentToken()) {
|
||||
case VALUE_NUMBER:
|
||||
case VALUE_STRING:
|
||||
lat = parser.doubleValue(true);
|
||||
try {
|
||||
lat = parser.doubleValue(true);
|
||||
} catch (NumberFormatException e) {
|
||||
numberFormatException = e;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new ElasticsearchParseException("latitude must be a number");
|
||||
|
@ -394,7 +399,11 @@ public class GeoUtils {
|
|||
switch (parser.currentToken()) {
|
||||
case VALUE_NUMBER:
|
||||
case VALUE_STRING:
|
||||
lon = parser.doubleValue(true);
|
||||
try {
|
||||
lon = parser.doubleValue(true);
|
||||
} catch (NumberFormatException e) {
|
||||
numberFormatException = e;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new ElasticsearchParseException("longitude must be a number");
|
||||
|
@ -419,6 +428,9 @@ public class GeoUtils {
|
|||
} else {
|
||||
return point.resetFromGeoHash(geohash);
|
||||
}
|
||||
} else if (numberFormatException != null) {
|
||||
throw new ElasticsearchParseException("[{}] and [{}] must be valid double values", numberFormatException, LATITUDE,
|
||||
LONGITUDE);
|
||||
} else if (Double.isNaN(lat)) {
|
||||
throw new ElasticsearchParseException("field [{}] missing", LATITUDE);
|
||||
} else if (Double.isNaN(lon)) {
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.lucene.document.Field;
|
|||
import org.apache.lucene.spatial.util.GeoHashUtils;
|
||||
import org.apache.lucene.util.LegacyNumericUtils;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.ElasticsearchParseException;
|
||||
import org.elasticsearch.common.Explicit;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.collect.Iterators;
|
||||
|
@ -431,8 +432,14 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr
|
|||
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) {
|
||||
parse(context, GeoUtils.parseGeoPoint(context.parser(), sparse), null);
|
||||
token = context.parser().nextToken();
|
||||
try {
|
||||
parse(context, GeoUtils.parseGeoPoint(context.parser(), sparse), null);
|
||||
} catch (ElasticsearchParseException e) {
|
||||
if (ignoreMalformed.value() == false) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
token = context.parser().nextToken();
|
||||
}
|
||||
} else {
|
||||
// its an array of other possible values
|
||||
|
@ -447,16 +454,28 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr
|
|||
if (token == XContentParser.Token.VALUE_STRING) {
|
||||
parsePointFromString(context, sparse, context.parser().text());
|
||||
} else {
|
||||
parse(context, GeoUtils.parseGeoPoint(context.parser(), sparse), null);
|
||||
try {
|
||||
parse(context, GeoUtils.parseGeoPoint(context.parser(), sparse), null);
|
||||
} catch (ElasticsearchParseException e) {
|
||||
if (ignoreMalformed.value() == false) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
token = context.parser().nextToken();
|
||||
token = context.parser().nextToken();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (token == XContentParser.Token.VALUE_STRING) {
|
||||
parsePointFromString(context, sparse, context.parser().text());
|
||||
} else if (token != XContentParser.Token.VALUE_NULL) {
|
||||
parse(context, GeoUtils.parseGeoPoint(context.parser(), sparse), null);
|
||||
try {
|
||||
parse(context, GeoUtils.parseGeoPoint(context.parser(), sparse), null);
|
||||
} catch (ElasticsearchParseException e) {
|
||||
if (ignoreMalformed.value() == false) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,11 +43,13 @@ import org.elasticsearch.test.geo.RandomGeoGenerator;
|
|||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.lang.NumberFormatException;
|
||||
|
||||
import static org.apache.lucene.spatial.util.GeoEncodingUtils.mortonHash;
|
||||
import static org.apache.lucene.spatial.util.GeoHashUtils.stringEncode;
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
@ -282,6 +284,42 @@ public class GeoPointFieldMapperTests extends ESSingleNodeTestCase {
|
|||
} catch (MapperParsingException e) {
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
defaultMapper.parse("test", "type", "1", XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.startObject("point").field("lat", "-").field("lon", 1.3).endObject()
|
||||
.endObject()
|
||||
.bytes());
|
||||
fail();
|
||||
} catch (MapperParsingException e) {
|
||||
assertThat(e.getRootCause(), instanceOf(NumberFormatException.class));
|
||||
assertThat(e.getRootCause().toString(), containsString("java.lang.NumberFormatException: For input string: \"-\""));
|
||||
}
|
||||
|
||||
try {
|
||||
defaultMapper.parse("test", "type", "1", XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.startObject("point").field("lat", 1.2).field("lon", "-").endObject()
|
||||
.endObject()
|
||||
.bytes());
|
||||
fail();
|
||||
} catch (MapperParsingException e) {
|
||||
assertThat(e.getRootCause(), instanceOf(NumberFormatException.class));
|
||||
assertThat(e.getRootCause().toString(), containsString("java.lang.NumberFormatException: For input string: \"-\""));
|
||||
}
|
||||
|
||||
try {
|
||||
defaultMapper.parse("test", "type", "1", XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.startObject("point").field("lat", "-").field("lon", "-").endObject()
|
||||
.endObject()
|
||||
.bytes());
|
||||
fail();
|
||||
} catch (MapperParsingException e) {
|
||||
assertThat(e.getRootCause(), instanceOf(NumberFormatException.class));
|
||||
assertThat(e.getRootCause().toString(), containsString("java.lang.NumberFormatException: For input string: \"-\""));
|
||||
}
|
||||
}
|
||||
|
||||
public void testNoValidateLatLonValues() throws Exception {
|
||||
|
@ -325,6 +363,24 @@ public class GeoPointFieldMapperTests extends ESSingleNodeTestCase {
|
|||
.startObject("point").field("lat", 1.2).field("lon", 181).endObject()
|
||||
.endObject()
|
||||
.bytes());
|
||||
|
||||
defaultMapper.parse("test", "type", "1", XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.startObject("point").field("lat", "-").field("lon", 1.3).endObject()
|
||||
.endObject()
|
||||
.bytes());
|
||||
|
||||
defaultMapper.parse("test", "type", "1", XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.startObject("point").field("lat", 1.2).field("lon", "-").endObject()
|
||||
.endObject()
|
||||
.bytes());
|
||||
|
||||
defaultMapper.parse("test", "type", "1", XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.startObject("point").field("lat", "-").field("lon", "-").endObject()
|
||||
.endObject()
|
||||
.bytes());
|
||||
}
|
||||
|
||||
public void testLatLonValuesStored() throws Exception {
|
||||
|
|
Loading…
Reference in New Issue