Skip to content

Commit d312ee0

Browse files
committed
improved error message for incorrect timestamp format
1 parent b17403b commit d312ee0

4 files changed

Lines changed: 33 additions & 13 deletions

File tree

src/main/java/com/teragrep/pth10/ast/DefaultTimeFormat.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,30 +75,35 @@ public long getEpoch(String time) {
7575
public Date parse(String time) {
7676
// Try parsing all the three default timeformats
7777
Date date;
78-
78+
final String defaultFormat = "MM/dd/yyyy:HH:mm:ss";
79+
final String withTimezone = "yyyy-MM-dd'T'HH:mm:ssXXX";
80+
final String withoutTimezone = "yyyy-MM-dd'T'HH:mm:ss";
7981
int attempt = 0;
8082
while (true) {
8183
try {
8284
if (attempt == 0) {
8385
// Use default format (MM/dd/yyyy:HH:mm:ss)
8486
// Use system default timezone
85-
date = this.parseDate(time, "MM/dd/yyyy:HH:mm:ss");
87+
date = this.parseDate(time, defaultFormat);
8688
}
8789
else if (attempt == 1) {
8890
// On first fail, try ISO 8601 with timezone offset, e.g. '2011-12-03T10:15:30+01:00'
89-
date = this.parseDate(time, "yyyy-MM-dd'T'HH:mm:ssXXX");
91+
date = this.parseDate(time, withTimezone);
9092
}
9193
else {
9294
// On second fail, try ISO 8601 without offset, e.g. '2011-12-03T10:15:30'
9395
// Use system default timezone
94-
date = this.parseDate(time, "yyyy-MM-dd'T'HH:mm:ss");
96+
date = this.parseDate(time, withoutTimezone);
9597
}
9698
break;
9799

98100
}
99-
catch (ParseException e) {
101+
catch (final ParseException e) {
100102
if (attempt > 1) {
101-
throw new RuntimeException("TimeQualifier conversion error: <" + time + "> can't be parsed.");
103+
throw new RuntimeException(
104+
"Check that the timestamp or the relative time value is in the correct format (Supported timestamp formats <"
105+
+ defaultFormat + ">, <" + withoutTimezone + ">, <" + withTimezone + ">)"
106+
);
102107
}
103108
}
104109
finally {

src/main/java/com/teragrep/pth10/ast/time/EpochTimestamp.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,16 @@
4949
import com.teragrep.pth10.ast.DefaultTimeFormat;
5050
import com.teragrep.pth10.ast.TextString;
5151
import com.teragrep.pth10.ast.UnquotedText;
52+
import org.slf4j.Logger;
53+
import org.slf4j.LoggerFactory;
5254

5355
import java.sql.Timestamp;
5456
import java.text.ParseException;
5557
import java.util.Objects;
5658

5759
public final class EpochTimestamp {
5860

61+
private static final Logger LOGGER = LoggerFactory.getLogger(EpochTimestamp.class);
5962
private final String value;
6063
private final String timeformat;
6164

@@ -71,19 +74,28 @@ public long epoch() {
7174
rv = relativeTimestamp.calculate(new Timestamp(System.currentTimeMillis()));
7275
}
7376
catch (NumberFormatException ne) {
74-
rv = epochFromString(value, timeformat);
77+
LOGGER.debug("Could not parse relative timestamp, trying default formats");
78+
rv = epochFromString(value, timeformat, ne);
7579
}
7680

7781
return rv;
7882
}
7983

8084
// Uses defaultTimeFormat if timeformat is null and DPLTimeFormat if timeformat isn't null (which means that the
8185
// timeformat= option was used).
82-
private long epochFromString(final String value, final String timeFormatString) {
86+
private long epochFromString(final String value, final String timeFormatString, final NumberFormatException cause) {
8387
final String unquotedValue = new UnquotedText(new TextString(value)).read(); // erase the possible outer quotes
8488
final long timevalue;
8589
if (timeFormatString == null || timeFormatString.isEmpty()) {
86-
timevalue = new DefaultTimeFormat().getEpoch(unquotedValue);
90+
try {
91+
timevalue = new DefaultTimeFormat().getEpoch(unquotedValue);
92+
}
93+
catch (final RuntimeException ex) {
94+
throw new RuntimeException(
95+
"Error parsing <" + unquotedValue + ">. " + ex.getMessage() + ". " + cause.getMessage() + ".",
96+
cause
97+
);
98+
}
8799
}
88100
else {
89101
// TODO: should be included in DPLTimeFormat

src/test/java/com/teragrep/pth10/EarliestLatestTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,10 @@ public void defaultFormatInvalidInputTest() { // MM/dd/yyyy:HH:mm:ss 2013-07-15
343343
.performThrowingDPLTest(RuntimeException.class, query, this.testFile, res -> {
344344
});
345345
Assertions
346-
.assertEquals("TimeQualifier conversion error: <31/31/2014:00:00:00> can't be parsed.", sqe.getMessage());
346+
.assertEquals(
347+
"Error parsing <31/31/2014:00:00:00>. Check that the timestamp or the relative time value is in the correct format (Supported timestamp formats <MM/dd/yyyy:HH:mm:ss>, <yyyy-MM-dd'T'HH:mm:ss>, <yyyy-MM-dd'T'HH:mm:ssXXX>). Unknown relative time modifier string [31/31/2014:00:00:00].",
348+
sqe.getMessage()
349+
);
347350
}
348351

349352
@Test

src/test/java/com/teragrep/pth10/relativeTimeTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ public void parseTimestampLatestRelativeTestWithPlus() {
336336
)
337337
public void parseTimestampLatestRelativeTestWithoutSign() {
338338
String q = "index=cinnamon latest=3h ";
339-
String expected = "TimeQualifier conversion error: <3h> can't be parsed.";
339+
String expected = "Error parsing <3h>. Check that the timestamp or the relative time value is in the correct format (Supported timestamp formats <MM/dd/yyyy:HH:mm:ss>, <yyyy-MM-dd'T'HH:mm:ss>, <yyyy-MM-dd'T'HH:mm:ssXXX>). Unknown relative time modifier string [3h].";
340340

341341
RuntimeException exception = this.streamingTestUtil
342342
.performThrowingDPLTest(RuntimeException.class, q, this.testFile, res -> {
@@ -422,7 +422,7 @@ public void parseTimestampEarliestRelativeSnapToDayLatestNow() {
422422
String expectedLatestString = String.valueOf(expectedLatest).substring(0, 7); // don't check last 2 numbers as the query takes some time and the "now" is different
423423
String regex = "^.*_time >= from_unixtime\\(" + expectedEarliest + ".*_time < from_unixtime\\("
424424
+ expectedLatestString + ".*$";
425-
;
425+
426426
String result = this.streamingTestUtil.getCtx().getSparkQuery();
427427
Assertions.assertTrue(result.matches(regex));
428428
});
@@ -437,7 +437,7 @@ public void parseTimestampEarliestRelativeSnapToDayLatestNow() {
437437
public void parseTimestampRelativeInvalidSnapToTimeUnitTest() {
438438
// pth10 ticket #66 query: 'index=... sourcetype=... earliest=@-5h latest=@-3h'
439439
String query = "index=cinnamon earliest=\"@-5h\" latest=\"@-3h\"";
440-
String expected = "TimeQualifier conversion error: <@-5h> can't be parsed.";
440+
String expected = "Error parsing <@-5h>. Check that the timestamp or the relative time value is in the correct format (Supported timestamp formats <MM/dd/yyyy:HH:mm:ss>, <yyyy-MM-dd'T'HH:mm:ss>, <yyyy-MM-dd'T'HH:mm:ssXXX>). Unknown relative time modifier string [@-5h].";
441441

442442
RuntimeException exception = this.streamingTestUtil
443443
.performThrowingDPLTest(RuntimeException.class, query, this.testFile, res -> {

0 commit comments

Comments
 (0)