This dependency-less library serves for one simple purpose: reduce boilerplate try-catch statements during work with Java Stream API.
- Maven
<dependency>
<groupId>io.github.suppierk</groupId>
<artifactId>java-throwable-utils</artifactId>
<version>2.0.0</version>
</dependency>
- Gradle
dependencies {
implementation 'io.github.suppierk:java-throwable-utils:2.0.0'
}
If you had to use constructs like:
import java.util.ArrayList;
import java.util.List;
public class Demo {
public static String throwingMethod(String source) throws Exception {
throw new Exception(source);
}
public static void main(String[] args) {
List<String> test = new ArrayList<>();
test.add("sample");
try {
test.stream()
.map(s -> {
try {
return throwingMethod(s);
} catch (Exception e) {
// Here we would have to:
// a) Return some value to filter out later and log exception
// b) Wrap and rethrow an exception to catch it later again
throw new RuntimeException(e);
}
})
.forEach(s -> {
try {
throwingMethod(s);
} catch (Exception e) {
// Here we would have to:
// a) Suppress and log exception
// b) Wrap and rethrow an exception to catch it later again
throw new RuntimeException(e);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
with this library, you can simplify this pipeline to:
import io.github.suppierk.java.util.function.*;
import java.util.ArrayList;
import java.util.List;
public class Demo {
public static String throwingMethod(String source) throws Exception {
throw new Exception(source);
}
public static void main(String[] args) {
List<String> test = new ArrayList<>();
test.add("sample");
try {
test.stream()
.map((ThrowableFunction<String, String>) Demo::throwingMethod)
.forEach((ThrowableConsumer<String>) Demo::throwingMethod);
} catch (Exception e) {
e.printStackTrace();
}
}
}
and you can take it further and define functions explicitly, removing the need to specify function types:
import io.github.suppierk.java.util.function.*;
import java.util.ArrayList;
import java.util.List;
public class Demo {
public static ThrowableFunction<String, String> throwingMap() {
return source -> {
throw new Exception(source);
};
}
public static ThrowableConsumer<String> throwingConsumer() {
return source -> {
throw new Exception(source);
};
}
public static void main(String[] args) {
List<String> test = new ArrayList<>();
test.add("sample");
try {
test.stream().map(Demo.throwingMap()).forEach(Demo.throwingConsumer());
} catch (Exception e) {
e.printStackTrace();
}
}
}
or with the help of UnsafeFunctions
utility class you can shorten it even more without changing your logic too much:
This is the recommended, the least intrusive and the least verbose way
import static io.github.suppierk.java.UnsafeFunctions.*;
import java.util.ArrayList;
import java.util.List;
public class Demo {
public static String throwingMethod(String source) throws Exception {
throw new Exception(source);
}
public static void main(String[] args) {
List<String> test = new ArrayList<>();
test.add("sample");
try {
test.stream()
.map(unsafeFunction(Demo::throwingMethod))
.forEach(unsafeConsumer(Demo::throwingMethod));
} catch (Exception e) {
e.printStackTrace();
}
}
}
All exceptions will be propagated using neat trick similar to Apache Commons ExceptionUtils.rethrow
by leveraging Java
type erasure to make checked exceptions unchecked.
This library has simple implementation of Try
, which benefits greatly from presence of these functions
and allows us to handle exceptions in functional style much like you deal with nullable values using Optional
.
import io.github.suppierk.java.Try;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class Test {
public String throwingMethod(String source) throws Exception {
throw new Exception(source);
}
public void processingMethod() {
List<String> test = new ArrayList<>();
test.stream()
.map(s -> Try.of(() -> throwingMethod(s)))
.filter(Try::isSuccess)
.collect(Collectors.toList());
}
}
Same as for Optional
, Try
in a case of failure will preserve only first exception happened in a call chain and skip
further operations.