Skip to content

Commit

Permalink
Introducing ThrowingSupplier to deal with checked exception on Supplier
Browse files Browse the repository at this point in the history
  • Loading branch information
VassilisSoum committed Aug 13, 2024
1 parent c454469 commit f797c78
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 4 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Then, you can add the dependency to your project.
<dependency>
<groupId>com.github.VassilisSoum</groupId>
<artifactId>FunctionalUtils</artifactId>
<version>1.8.0</version>
<version>2.0.0</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.soumakis</groupId>
<artifactId>FunctionalUtils</artifactId>
<version>1.8.0</version>
<version>2.0.0</version>
<packaging>jar</packaging>

<properties>
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/com/soumakis/control/Try.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.soumakis.control;

import com.soumakis.safetype.ThrowingSupplier;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
Expand All @@ -10,7 +11,7 @@
* Represents a computation that may either result in an exception, or return a successfully
* computed value. It's a functional programming concept used to handle exceptions in a more
* functional way.
*
* <p>
* Example usage:
* <ul>
* <li> {@code Try<Integer> result = Try.of(() -> 1 / 0);}</li>
Expand Down Expand Up @@ -93,7 +94,7 @@ public sealed interface Try<T> permits Success, Failure {
* @param <T> the type of the result of the computation
* @return a {@code Try} instance representing the outcome of the computation
*/
static <T> Try<T> of(Supplier<T> fn) {
static <T> Try<T> of(ThrowingSupplier<T> fn) {
try {
return new Success<>(fn.get());
} catch (Throwable throwable) {
Expand Down
49 changes: 49 additions & 0 deletions src/main/java/com/soumakis/safetype/ThrowingSupplier.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.soumakis.safetype;

import java.util.function.BiFunction;
import java.util.function.Supplier;

/**
* A {@link Supplier} that allows invocation of code that throws a checked exception.
*
* @param <T> the type of results supplied by this supplier
*/
public interface ThrowingSupplier<T> extends Supplier<T> {

/**
* Gets a result, possibly throwing a checked exception.
*
* @return a result
* @throws Exception on error
*/
T getWithException() throws Exception;

/**
* Default {@link Supplier#get()} that wraps any thrown checked exceptions (by default in a
* {@link RuntimeException}).
*
* @see java.util.function.Supplier#get()
*/
@Override
default T get() {
return get(RuntimeException::new);
}

/**
* Gets a result, wrapping any thrown checked exceptions using the given
* {@code exceptionWrapper}.
*
* @param exceptionWrapper {@link BiFunction} that wraps the given message and checked exception
* into a runtime exception
* @return a result
*/
default T get(BiFunction<String, Exception, RuntimeException> exceptionWrapper) {
try {
return getWithException();
} catch (RuntimeException ex) {
throw ex;
} catch (Exception ex) {
throw exceptionWrapper.apply(ex.getMessage(), ex);
}
}
}
31 changes: 31 additions & 0 deletions src/test/java/com/soumakis/safetype/ThrowingSupplierTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.soumakis.safetype;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import org.junit.jupiter.api.Test;

public class ThrowingSupplierTest {

@Test
void testGet() {
ThrowingSupplier<Integer> supplier = () -> 1;
assertEquals(1, supplier.get());
}

@Test
void testGetWithException() {
ThrowingSupplier<Integer> supplier = () -> {
throw new Exception("Test exception");
};
assertThrows(RuntimeException.class, supplier::get);
}

@Test
void testGetWithExceptionCustomWrapper() {
ThrowingSupplier<Integer> supplier = () -> {
throw new Exception("Test exception");
};
assertThrows(IllegalStateException.class, () -> supplier.get((msg, ex) -> new IllegalStateException(msg, ex)));
}
}

0 comments on commit f797c78

Please sign in to comment.