diff --git a/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/ExceptionUtils.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/ExceptionUtils.java new file mode 100644 index 00000000..1eb6a4ae --- /dev/null +++ b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/ExceptionUtils.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) Gustav Karlsson + * + *
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + *
http://www.apache.org/licenses/LICENSE-2.0 + * + *
Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.kagkarlsson.scheduler; + +final class ExceptionUtils { + + static String describe(Throwable t) { + if (t == null) { + return null; + } + + String typeDescription = t.getClass().getSimpleName(); + String message = t.getMessage(); + return typeDescription + (message != null ? ": '" + message + "'" : ""); + } + + private ExceptionUtils() {} +} diff --git a/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/ExecutePicked.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/ExecutePicked.java index c5564d15..99df0884 100644 --- a/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/ExecutePicked.java +++ b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/ExecutePicked.java @@ -13,6 +13,8 @@ */ package com.github.kagkarlsson.scheduler; +import static com.github.kagkarlsson.scheduler.ExceptionUtils.describe; + import com.github.kagkarlsson.scheduler.logging.ConfigurableLogger; import com.github.kagkarlsson.scheduler.stats.StatsRegistry; import com.github.kagkarlsson.scheduler.task.CompletionHandler; @@ -129,9 +131,10 @@ private void complete( statsRegistry.register(StatsRegistry.SchedulerStatsEvent.COMPLETIONHANDLER_ERROR); statsRegistry.register(StatsRegistry.SchedulerStatsEvent.UNEXPECTED_ERROR); LOG.error( - "Failed while completing execution {}. Execution will likely remain scheduled and locked/picked. " + "Failed while completing execution {}, because {}. Execution will likely remain scheduled and locked/picked. " + "The execution should be detected as dead after a while, and handled according to the tasks DeadExecutionHandler.", execution, + describe(e), e); } } @@ -143,7 +146,10 @@ private void failure( Instant executionStarted, String errorMessagePrefix) { String logMessage = - errorMessagePrefix + " during execution of task with name '{}'. Treating as failure."; + errorMessagePrefix + + " " + + describe(cause) + + " during execution of task with name '{}'. Treating as failure."; failureLogger.log(logMessage, cause, task.getName()); ExecutionComplete completeEvent = @@ -158,9 +164,10 @@ private void failure( statsRegistry.register(StatsRegistry.SchedulerStatsEvent.FAILUREHANDLER_ERROR); statsRegistry.register(StatsRegistry.SchedulerStatsEvent.UNEXPECTED_ERROR); LOG.error( - "Failed while completing execution {}. Execution will likely remain scheduled and locked/picked. " + "Failed while completing execution {}, because {}. Execution will likely remain scheduled and locked/picked. " + "The execution should be detected as dead after a while, and handled according to the tasks DeadExecutionHandler.", execution, + describe(cause), e); } } diff --git a/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/ExceptionUtilsTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/ExceptionUtilsTest.java new file mode 100644 index 00000000..6f638ea4 --- /dev/null +++ b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/ExceptionUtilsTest.java @@ -0,0 +1,28 @@ +package com.github.kagkarlsson.scheduler; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; + +import java.io.IOException; +import org.junit.jupiter.api.Test; + +class ExceptionUtilsTest { + + @Test + void exceptionWithNoMessageDescribedAsItsClassSimpleName() { + assertThat( + ExceptionUtils.describe(new IllegalArgumentException()), is("IllegalArgumentException")); + } + + @Test + void exceptionDescribedAsClassSimpleNameAndMessage() { + assertThat( + ExceptionUtils.describe(new IOException("timed out")), is("IOException: 'timed out'")); + } + + @Test + void describingNullIsNull() { + assertThat(ExceptionUtils.describe(null), is(nullValue())); + } +}