Skip to content

Commit 2060c65

Browse files
authored
Merge pull request #831 from HubSpot/warn-bad-date-arithmetic
Don't throw exceptions on bad date arithmetic
2 parents a937685 + 0e95cb9 commit 2060c65

4 files changed

Lines changed: 87 additions & 21 deletions

File tree

src/main/java/com/hubspot/jinjava/lib/filter/MinusTimeFilter.java

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@
44
import com.hubspot.jinjava.doc.annotations.JinjavaParam;
55
import com.hubspot.jinjava.doc.annotations.JinjavaSnippet;
66
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
7+
import com.hubspot.jinjava.interpret.TemplateError;
8+
import com.hubspot.jinjava.interpret.TemplateError.ErrorItem;
9+
import com.hubspot.jinjava.interpret.TemplateError.ErrorReason;
10+
import com.hubspot.jinjava.interpret.TemplateError.ErrorType;
711
import com.hubspot.jinjava.lib.fn.Functions;
812
import com.hubspot.jinjava.objects.date.PyishDate;
13+
import java.time.DateTimeException;
914
import java.time.ZoneOffset;
1015
import java.time.ZonedDateTime;
1116
import java.time.temporal.ChronoUnit;
@@ -43,16 +48,31 @@ public Object filter(
4348
long diff = parseDiffAmount(interpreter, args);
4449
ChronoUnit chronoUnit = parseChronoUnit(interpreter, args);
4550

46-
if (var instanceof ZonedDateTime) {
47-
ZonedDateTime dateTime = (ZonedDateTime) var;
48-
return new PyishDate(dateTime.minus(diff, chronoUnit));
49-
} else if (var instanceof PyishDate) {
50-
PyishDate pyishDate = (PyishDate) var;
51-
return new PyishDate(pyishDate.toDateTime().minus(diff, chronoUnit));
52-
} else if (var instanceof Number) {
53-
Number timestamp = (Number) var;
54-
ZonedDateTime zonedDateTime = Functions.getDateTimeArg(timestamp, ZoneOffset.UTC);
55-
return new PyishDate(zonedDateTime.minus(diff, chronoUnit));
51+
try {
52+
if (var instanceof ZonedDateTime) {
53+
ZonedDateTime dateTime = (ZonedDateTime) var;
54+
return new PyishDate(dateTime.minus(diff, chronoUnit));
55+
} else if (var instanceof PyishDate) {
56+
PyishDate pyishDate = (PyishDate) var;
57+
return new PyishDate(pyishDate.toDateTime().minus(diff, chronoUnit));
58+
} else if (var instanceof Number) {
59+
Number timestamp = (Number) var;
60+
ZonedDateTime zonedDateTime = Functions.getDateTimeArg(timestamp, ZoneOffset.UTC);
61+
return new PyishDate(zonedDateTime.minus(diff, chronoUnit));
62+
}
63+
} catch (DateTimeException e) {
64+
interpreter.addError(
65+
new TemplateError(
66+
ErrorType.WARNING,
67+
ErrorReason.OTHER,
68+
ErrorItem.FILTER,
69+
e.getMessage(),
70+
null,
71+
interpreter.getLineNumber(),
72+
interpreter.getPosition(),
73+
e
74+
)
75+
);
5676
}
5777

5878
return var;

src/main/java/com/hubspot/jinjava/lib/filter/PlusTimeFilter.java

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@
44
import com.hubspot.jinjava.doc.annotations.JinjavaParam;
55
import com.hubspot.jinjava.doc.annotations.JinjavaSnippet;
66
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
7+
import com.hubspot.jinjava.interpret.TemplateError;
8+
import com.hubspot.jinjava.interpret.TemplateError.ErrorItem;
9+
import com.hubspot.jinjava.interpret.TemplateError.ErrorReason;
10+
import com.hubspot.jinjava.interpret.TemplateError.ErrorType;
711
import com.hubspot.jinjava.lib.fn.Functions;
812
import com.hubspot.jinjava.objects.date.PyishDate;
13+
import java.time.DateTimeException;
914
import java.time.ZoneOffset;
1015
import java.time.ZonedDateTime;
1116
import java.time.temporal.ChronoUnit;
@@ -43,18 +48,32 @@ public Object filter(
4348
long diff = parseDiffAmount(interpreter, args);
4449
ChronoUnit chronoUnit = parseChronoUnit(interpreter, args);
4550

46-
if (var instanceof ZonedDateTime) {
47-
ZonedDateTime dateTime = (ZonedDateTime) var;
48-
return new PyishDate(dateTime.plus(diff, chronoUnit));
49-
} else if (var instanceof PyishDate) {
50-
PyishDate pyishDate = (PyishDate) var;
51-
return new PyishDate(pyishDate.toDateTime().plus(diff, chronoUnit));
52-
} else if (var instanceof Number) {
53-
Number timestamp = (Number) var;
54-
ZonedDateTime zonedDateTime = Functions.getDateTimeArg(timestamp, ZoneOffset.UTC);
55-
return new PyishDate(zonedDateTime.plus(diff, chronoUnit));
51+
try {
52+
if (var instanceof ZonedDateTime) {
53+
ZonedDateTime dateTime = (ZonedDateTime) var;
54+
return new PyishDate(dateTime.plus(diff, chronoUnit));
55+
} else if (var instanceof PyishDate) {
56+
PyishDate pyishDate = (PyishDate) var;
57+
return new PyishDate(pyishDate.toDateTime().plus(diff, chronoUnit));
58+
} else if (var instanceof Number) {
59+
Number timestamp = (Number) var;
60+
ZonedDateTime zonedDateTime = Functions.getDateTimeArg(timestamp, ZoneOffset.UTC);
61+
return new PyishDate(zonedDateTime.plus(diff, chronoUnit));
62+
}
63+
} catch (DateTimeException e) {
64+
interpreter.addError(
65+
new TemplateError(
66+
ErrorType.WARNING,
67+
ErrorReason.OTHER,
68+
ErrorItem.FILTER,
69+
e.getMessage(),
70+
null,
71+
interpreter.getLineNumber(),
72+
interpreter.getPosition(),
73+
e
74+
)
75+
);
5676
}
57-
5877
return var;
5978
}
6079

src/test/java/com/hubspot/jinjava/lib/filter/MinusTimeFilterTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import com.google.common.collect.ImmutableMap;
66
import com.hubspot.jinjava.BaseJinjavaTest;
7+
import com.hubspot.jinjava.interpret.RenderResult;
78
import com.hubspot.jinjava.objects.date.PyishDate;
89
import java.time.Instant;
910
import java.time.ZoneOffset;
@@ -57,4 +58,17 @@ public void itSubtractsTime() {
5758
assertThat(jinjava.render("{{ test|minus_time(1, 'days')|unixtimestamp }}", vars))
5859
.isEqualTo(String.valueOf(oneDay));
5960
}
61+
62+
@Test
63+
public void itWarnsOnDateTimeException() {
64+
long timestamp = 1543352736000L;
65+
66+
Map<String, Object> vars = ImmutableMap.of("test", timestamp);
67+
RenderResult renderResult = jinjava.renderForResult(
68+
"{{ test|minus_time(9999999999, 'years')|unixtimestamp }}",
69+
vars
70+
);
71+
assertThat(renderResult.getOutput()).isEqualTo(String.valueOf(timestamp));
72+
assertThat(renderResult.getErrors()).hasSize(1);
73+
}
6074
}

src/test/java/com/hubspot/jinjava/lib/filter/PlusTimeFilterTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,17 @@ public void itErrorsOnInvalidTemporalUnit() {
9898
);
9999
assertThat(renderResult.getErrors()).hasSize(1);
100100
}
101+
102+
@Test
103+
public void itWarnsOnDateTimeException() {
104+
long timestamp = 1543352736000L;
105+
106+
Map<String, Object> vars = ImmutableMap.of("test", timestamp);
107+
RenderResult renderResult = jinjava.renderForResult(
108+
"{{ test|plus_time(9999999999, 'years')|unixtimestamp }}",
109+
vars
110+
);
111+
assertThat(renderResult.getOutput()).isEqualTo(String.valueOf(timestamp));
112+
assertThat(renderResult.getErrors()).hasSize(1);
113+
}
101114
}

0 commit comments

Comments
 (0)