--- /dev/null
+package net.pterodactylus.util.exception
+
+/**
+ * Runs the given [runnable][Runnable], catching any [exceptions][Exception],
+ * and running the [errorRunnable][Runnable] with a caught exception.
+ *
+ * @param runnable The block to run
+ * @param errorRunnable The block to run in case of an exception
+ */
+fun suppressException(runnable: () -> Unit = {}, errorRunnable: (e: Exception) -> Unit = {}): () -> Unit = {
+ try {
+ runnable()
+ } catch (e: Exception) {
+ errorRunnable(e)
+ }
+}
--- /dev/null
+package net.pterodactylus.util.exception
+
+import org.hamcrest.MatcherAssert
+import org.hamcrest.Matchers
+import org.junit.Test
+import java.util.concurrent.atomic.AtomicBoolean
+import java.util.concurrent.atomic.AtomicReference
+
+class ExceptionsTest {
+
+ @Test
+ fun `runnable is run by suppress method`() {
+ val runnabledCalled = AtomicBoolean(false)
+ suppressException({ runnabledCalled.set(true) })()
+ MatcherAssert.assertThat(runnabledCalled.get(), Matchers.equalTo(true))
+ }
+
+ @Test
+ fun `exception thrown in runnable is suppressed`() {
+ suppressException({ throw RuntimeException() })()
+ }
+
+ @Test
+ fun `error runnable is called with exception`() {
+ val caughtException = AtomicReference<Exception>()
+ suppressException({ throw IllegalStateException("Test") }) { caughtException.set(it) }()
+ MatcherAssert.assertThat(caughtException.get(), Matchers.instanceOf(RuntimeException::class.java))
+ MatcherAssert.assertThat(caughtException.get().message, Matchers.equalTo("Test"))
+ }
+
+}