Skip to content

Commit

Permalink
Don't dump a stacktrace for invalid patterns when executing elasticse…
Browse files Browse the repository at this point in the history
…arch-croneval (elastic#49744)
  • Loading branch information
gaobinlong authored and SivagurunathanV committed Jan 21, 2020
1 parent 5d5fe81 commit 76355c7
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 36 deletions.
6 changes: 5 additions & 1 deletion docs/reference/commands/croneval.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ This command is provided in the `$ES_HOME/bin` directory.
`-c, --count` <Integer>::
The number of future times this expression will be triggered. The default
value is `10`.


`-d, --detail`::
Shows detail for invalid cron expression. It will print the stacktrace if the
expression is not valid.

`-h, --help`::
Returns all of the command parameters.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,16 @@ public static void main(String[] args) throws Exception {

private final OptionSpec<Integer> countOption;
private final OptionSpec<String> arguments;
private final OptionSpec<Void> detailOption;

CronEvalTool() {
super("Validates and evaluates a cron expression");
this.countOption = parser.acceptsAll(Arrays.asList("c", "count"),
"The number of future times this expression will be triggered")
.withRequiredArg().ofType(Integer.class).defaultsTo(10);
this.countOption = parser.acceptsAll(Arrays.asList("c", "count"), "The number of future times this expression will be triggered")
.withRequiredArg()
.ofType(Integer.class)
.defaultsTo(10);
this.arguments = parser.nonOptions("expression");
this.detailOption = parser.acceptsAll(Arrays.asList("d", "detail"), "Show detail for invalid cron expression");

parser.accepts("E", "Unused. Only for compatibility with other CLI tools.").withRequiredArg();
}
Expand All @@ -55,46 +58,63 @@ protected void execute(Terminal terminal, OptionSet options) throws Exception {
if (args.size() != 1) {
throw new UserException(ExitCodes.USAGE, "expecting a single argument that is the cron expression to evaluate");
}
execute(terminal, args.get(0), count);
boolean printDetail = options.has(detailOption);
execute(terminal, args.get(0), count, printDetail);
}

private void execute(Terminal terminal, String expression, int count) throws Exception {
Cron.validate(expression);
terminal.println("Valid!");
private void execute(Terminal terminal, String expression, int count, boolean printDetail) throws Exception {
try {
Cron.validate(expression);
terminal.println("Valid!");

final ZonedDateTime date = ZonedDateTime.now(ZoneOffset.UTC);
final boolean isLocalTimeUTC = UTC_FORMATTER.zone().equals(LOCAL_FORMATTER.zone());
if (isLocalTimeUTC) {
terminal.println("Now is [" + UTC_FORMATTER.format(date) + "] in UTC");
} else {
terminal.println("Now is [" + UTC_FORMATTER.format(date) + "] in UTC, local time is [" + LOCAL_FORMATTER.format(date) + "]");
final ZonedDateTime date = ZonedDateTime.now(ZoneOffset.UTC);
final boolean isLocalTimeUTC = UTC_FORMATTER.zone().equals(LOCAL_FORMATTER.zone());
if (isLocalTimeUTC) {
terminal.println("Now is [" + UTC_FORMATTER.format(date) + "] in UTC");
} else {
terminal.println(
"Now is [" + UTC_FORMATTER.format(date) + "] in UTC, local time is [" + LOCAL_FORMATTER.format(date) + "]"
);

}
terminal.println("Here are the next " + count + " times this cron expression will trigger:");

Cron cron = new Cron(expression);
long time = date.toInstant().toEpochMilli();

for (int i = 0; i < count; i++) {
long prevTime = time;
time = cron.getNextValidTimeAfter(time);
if (time < 0) {
if (i == 0) {
throw new UserException(ExitCodes.OK, "Could not compute future times since ["
+ UTC_FORMATTER.format(Instant.ofEpochMilli(prevTime)) + "] " + "(perhaps the cron expression only points to " +
"times in the" +
" " +
"past?)");
}
break;
}
terminal.println("Here are the next " + count + " times this cron expression will trigger:");

Cron cron = new Cron(expression);
long time = date.toInstant().toEpochMilli();

for (int i = 0; i < count; i++) {
long prevTime = time;
time = cron.getNextValidTimeAfter(time);
if (time < 0) {
if (i == 0) {
throw new UserException(
ExitCodes.OK,
"Could not compute future times since ["
+ UTC_FORMATTER.format(Instant.ofEpochMilli(prevTime))
+ "] "
+ "(perhaps the cron expression only points to "
+ "times in the"
+ " "
+ "past?)"
);
}
break;
}

if (isLocalTimeUTC) {
terminal.println((i + 1) + ".\t" + UTC_FORMATTER.format(Instant.ofEpochMilli(time)));
if (isLocalTimeUTC) {
terminal.println((i + 1) + ".\t" + UTC_FORMATTER.format(Instant.ofEpochMilli(time)));
} else {
terminal.println((i + 1) + ".\t" + UTC_FORMATTER.format(Instant.ofEpochMilli(time)));
terminal.println("\t" + LOCAL_FORMATTER.format(Instant.ofEpochMilli(time)));
}
}
} catch (Exception e) {
if (printDetail) {
throw e;
} else {
terminal.println((i + 1) + ".\t" + UTC_FORMATTER.format(Instant.ofEpochMilli(time)));
terminal.println("\t" + LOCAL_FORMATTER.format(Instant.ofEpochMilli(time)));
throw new UserException(ExitCodes.OK, e.getMessage() + (e.getCause() == null ? "" : ": " + e.getCause().getMessage()));
}

}
}
}

0 comments on commit 76355c7

Please sign in to comment.