Skip to content

Commit 11fab60

Browse files
committed
[Watcher] Improved error messages for CronEvalTool
CronEvalTool prints an error only for cron expressions that result in no coming time events. If a cron expression results in less than the specified `-count` (default 10) time events, the CronEvalTool prints all the coming times and displays no error message. Fixes elastic#32735
1 parent 8114646 commit 11fab60

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/trigger/schedule/tool/CronEvalTool.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
package org.elasticsearch.xpack.watcher.trigger.schedule.tool;
77

8+
import java.util.ArrayList;
89
import java.util.Arrays;
910
import java.util.List;
1011

@@ -57,18 +58,25 @@ void execute(Terminal terminal, String expression, int count) throws Exception {
5758

5859
DateTime date = DateTime.now(DateTimeZone.UTC);
5960
terminal.println("Now is [" + formatter.print(date) + "]");
60-
terminal.println("Here are the next " + count + " times this cron expression will trigger:");
6161

6262
Cron cron = new Cron(expression);
6363
long time = date.getMillis();
64-
for (int i = 0; i < count; i++) {
64+
int i = 0;
65+
List<String> times = new ArrayList<>();
66+
67+
for (; i < count; i++) {
6568
long prevTime = time;
6669
time = cron.getNextValidTimeAfter(time);
6770
if (time < 0) {
68-
throw new UserException(ExitCodes.OK, (i + 1) + ".\t Could not compute future times since ["
69-
+ formatter.print(prevTime) + "] " + "(perhaps the cron expression only points to times in the past?)");
71+
if (i == 0) {
72+
throw new UserException(ExitCodes.OK, "Could not compute future times since ["
73+
+ formatter.print(prevTime) + "] " + "(perhaps the cron expression only points to times in the past?)");
74+
}
75+
break;
7076
}
71-
terminal.println((i+1) + ".\t" + formatter.print(time));
77+
times.add((i + 1) + ".\t" + formatter.print(time));
7278
}
79+
terminal.println((i == count ? "Here are the next " : "There are ") + i + " times this cron expression will trigger:");
80+
times.forEach(terminal::println);
7381
}
7482
}

x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/trigger/schedule/tool/CronEvalToolTests.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
import org.elasticsearch.cli.Command;
99
import org.elasticsearch.cli.CommandTestCase;
1010

11+
import java.util.Calendar;
12+
import java.util.Locale;
13+
import java.util.TimeZone;
14+
1115
public class CronEvalToolTests extends CommandTestCase {
1216
@Override
1317
protected Command newCommand() {
@@ -20,4 +24,28 @@ public void testParse() throws Exception {
2024
String output = execute(countOption, Integer.toString(count), "0 0 0 1-6 * ?");
2125
assertTrue(output, output.contains("Here are the next " + count + " times this cron expression will trigger"));
2226
}
27+
28+
public void testGetNextValidTimes() throws Exception {
29+
{
30+
String output = execute(
31+
"0 3 23 8 9 ? " + (Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ROOT).get(Calendar.YEAR) + 1));
32+
assertTrue(output, output.contains("There are 1 times this cron expression will trigger:"));
33+
assertFalse(output.contains("ERROR"));
34+
assertFalse(output.contains("2.\t"));
35+
}
36+
{
37+
String output = execute(
38+
"0 3 23 */4 9 ? " + (Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ROOT).get(Calendar.YEAR) + 1));
39+
assertTrue(output, output.contains("There are 8 times this cron expression will trigger:"));
40+
assertFalse(output, output.contains("Here are the next 10 times this cron expression will trigger:"));
41+
assertFalse(output, output.contains("ERROR"));
42+
}
43+
{
44+
Exception expectThrows = expectThrows(Exception.class, () -> execute(
45+
"0 3 23 */4 9 ? " + (Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ROOT).get(Calendar.YEAR) - 1)));
46+
String message = expectThrows.getMessage();
47+
assertTrue(message, message.contains("Could not compute future times since"));
48+
assertTrue(message, message.contains("(perhaps the cron expression only points to times in the past?)"));
49+
}
50+
}
2351
}

0 commit comments

Comments
 (0)