Skip to content

Commit

Permalink
added runCatching method with specified exception types
Browse files Browse the repository at this point in the history
  • Loading branch information
evpl committed Mar 16, 2024
1 parent f78259c commit ac91346
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 2 deletions.
46 changes: 44 additions & 2 deletions src/main/java/com/plugatar/jkscope/JKScope.java
Expand Up @@ -75,6 +75,7 @@
* <ul>
* <li>{@link #run(ThRunnable)}</li>
* <li>{@link #runCatching(ThRunnable)}</li>
* <li>{@link #runCatching(ThRunnable, Class[])}</li>
* <li>{@link #runRec(ThConsumer)}</li>
* <li>{@link #with(Object, ThConsumer)}</li>
* <li>{@link #withInt(int, ThIntConsumer)}</li>
Expand Down Expand Up @@ -196,7 +197,7 @@ static void run(final ThRunnable<?> block) {
* Performs given function block and catching any {@link Throwable} exception.
* <pre>{@code
* runCatching(() -> {
* if(new Random().nextInt(0, 100) == 50) {
* if (new Random().nextInt(0, 100) == 50) {
* throw new Throwable();
* }
* });
Expand All @@ -212,11 +213,52 @@ static void runCatching(final ThRunnable<?> block) {
} catch (final Throwable ignored) { }
}

/**
* Performs given function block and catching specified {@link Throwable} exceptions.
* <pre>{@code
* runCatching(() -> {
* if (new Random().nextInt(0, 100) == 50) {
* throw new IllegalStateException();
* } else {
* throw new AssertionError();
* }
* }, RuntimeException.class, Error.class);
* }</pre>
*
* @param block the function block
* @param exceptionTypes the exception types array
* @throws NullPointerException if {@code block} or {@code exceptionTypes} arg is null or if {@code exceptionTypes}
* arg array contains null element
*/
@SafeVarargs
static void runCatching(final ThRunnable<?> block,
final Class<? extends Throwable>... exceptionTypes) {
blockArgNotNull(block);
if (exceptionTypes == null) { throw new NullPointerException("exceptionTypes arg is null"); }
for (int idx = 0; idx < exceptionTypes.length; idx++) {
if (exceptionTypes[idx] == null) {
throw new NullPointerException("exceptionTypes arg array contains null element at index " + idx);
}
}
ThBiConsumer.<ThRunnable<?>, Class<? extends Throwable>[]>unchecked((b, t) -> {
try {
b.run();
} catch (final Throwable exception) {
for (final Class<? extends Throwable> currentType : t) {
if (currentType.isInstance(exception)) {
return;
}
}
throw exception;
}
}).accept(block, exceptionTypes);
}

/**
* Performs given function block recursively.
* <pre>{@code
* runRec(func -> {
* if(new Random().nextInt(0, 100) == 50) {
* if (new Random().nextInt(0, 100) == 50) {
* func.run();
* }
* });
Expand Down
57 changes: 57 additions & 0 deletions src/test/java/com/plugatar/jkscope/JKScopeTest.java
Expand Up @@ -286,6 +286,37 @@ void runCatchingStaticMethodThrowsNPEForNullArg() {
.isInstanceOf(NullPointerException.class);
}

@Test
void runCatchingWithExceptionTypesStaticMethodThrowsNPEForNullBlockArg() {
final ThRunnable<Throwable> block = null;
@SuppressWarnings("unchecked")
final Class<? extends Throwable>[] exceptionTypes = (Class<? extends Throwable>[]) new Class[]{};

assertThatThrownBy(() -> JKScope.runCatching(block, exceptionTypes))
.isInstanceOf(NullPointerException.class);
}

@Test
void runCatchingWithExceptionTypesStaticMethodThrowsNPEForNullExceptionTypesArg() {
final ThRunnable<Throwable> block = () -> { };
final Class<? extends Throwable>[] exceptionTypes = null;

assertThatThrownBy(() -> JKScope.runCatching(block, exceptionTypes))
.isInstanceOf(NullPointerException.class);
}

@Test
void runCatchingWithExceptionTypesStaticMethodThrowsNPEForNullElementInExceptionTypesArg() {
final ThRunnable<Throwable> block = () -> { };
@SuppressWarnings("unchecked")
final Class<? extends Throwable>[] exceptionTypes = (Class<? extends Throwable>[]) new Class[]{
IllegalStateException.class, null, IllegalArgumentException.class
};

assertThatThrownBy(() -> JKScope.runCatching(block, exceptionTypes))
.isInstanceOf(NullPointerException.class);
}

@Test
void runRecStaticMethodThrowsNPEForNullArg() {
final ThConsumer<ThRunnable<Throwable>, Throwable> block = null;
Expand Down Expand Up @@ -610,6 +641,32 @@ void runCatchingStaticMethodThrowsException() {
.isTrue();
}

@Test
void runCatchingWithExceptionTypesStaticMethod() {
final AtomicBoolean sideEffect = new AtomicBoolean(false);
final ThRunnable<Throwable> block = () -> sideEffect.set(true);

JKScope.runCatching(block, IllegalArgumentException.class);
assertThat(sideEffect.get())
.isTrue();
}

@Test
void runCatchingWithExceptionTypesStaticMethodThrowsException() {
final AtomicBoolean sideEffect = new AtomicBoolean(false);
final ThRunnable<Throwable> block = () -> {
sideEffect.set(true);
throw new IllegalArgumentException();
};

JKScope.runCatching(block, IllegalArgumentException.class);
assertThat(sideEffect.get())
.isTrue();

assertThatThrownBy(() -> JKScope.runCatching(block, IllegalStateException.class))
.isInstanceOf(IllegalArgumentException.class);
}

@Test
void runRecStaticMethodThrowsException() {
final Throwable throwable = new Throwable();
Expand Down

0 comments on commit ac91346

Please sign in to comment.