From 3caf887632f1ec62a609a9285043688113cf0253 Mon Sep 17 00:00:00 2001 From: Stuart Neivandt Date: Tue, 28 Mar 2017 07:45:20 -0500 Subject: [PATCH] Improve error handling for epoch format parser with time zone (#23689) Change the error response when using a non UTF timezone for range queries with epoch_millis or epoch_second formats to an illegal argument exception. The goal is to provide a better explanation of why the query has failed. The current behavior is to respond with a parse exception. Closes #22621 --- .../org/elasticsearch/common/joda/Joda.java | 7 +++-- .../deps/joda/SimpleJodaTests.java | 30 +++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/common/joda/Joda.java b/core/src/main/java/org/elasticsearch/common/joda/Joda.java index 7978ceff48c..c9eaa9ab3aa 100644 --- a/core/src/main/java/org/elasticsearch/common/joda/Joda.java +++ b/core/src/main/java/org/elasticsearch/common/joda/Joda.java @@ -333,9 +333,10 @@ public class Joda { boolean isPositive = text.startsWith("-") == false; boolean isTooLong = text.length() > estimateParsedLength(); - if ((isPositive && isTooLong) || - // timestamps have to have UTC timezone - bucket.getZone() != DateTimeZone.UTC) { + if (bucket.getZone() != DateTimeZone.UTC) { + String format = hasMilliSecondPrecision ? "epoch_millis" : "epoch_second"; + throw new IllegalArgumentException("time_zone must be UTC for format [" + format + "]"); + } else if (isPositive && isTooLong) { return -1; } diff --git a/core/src/test/java/org/elasticsearch/deps/joda/SimpleJodaTests.java b/core/src/test/java/org/elasticsearch/deps/joda/SimpleJodaTests.java index 9ed433918d1..b99dd8e8353 100644 --- a/core/src/test/java/org/elasticsearch/deps/joda/SimpleJodaTests.java +++ b/core/src/test/java/org/elasticsearch/deps/joda/SimpleJodaTests.java @@ -314,6 +314,36 @@ public class SimpleJodaTests extends ESTestCase { } } + public void testForInvalidTimeZoneWithEpochSeconds() { + DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder() + .append(new Joda.EpochTimeParser(false)) + .toFormatter() + .withZone(DateTimeZone.forOffsetHours(1)); + FormatDateTimeFormatter formatter = + new FormatDateTimeFormatter("epoch_seconds", dateTimeFormatter, Locale.ROOT); + try { + formatter.parser().parseDateTime("1433144433655"); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { + assertThat(e.getMessage(), containsString("time_zone must be UTC")); + } + } + + public void testForInvalidTimeZoneWithEpochMillis() { + DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder() + .append(new Joda.EpochTimeParser(true)) + .toFormatter() + .withZone(DateTimeZone.forOffsetHours(1)); + FormatDateTimeFormatter formatter = + new FormatDateTimeFormatter("epoch_millis", dateTimeFormatter, Locale.ROOT); + try { + formatter.parser().parseDateTime("1433144433"); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { + assertThat(e.getMessage(), containsString("time_zone must be UTC")); + } + } + public void testThatEpochParserIsPrinter() { FormatDateTimeFormatter formatter = Joda.forPattern("epoch_millis"); assertThat(formatter.parser().isPrinter(), is(true));