noexception
HomeJavadocSources

NoException

NoException is a Java exception handling library. Many Java applications contain thousands of try-catch constructs and it's a mess. Catch clauses are verbose, repetitive, inconsistent, buggy, and hard to test.

NoException provides a set of predefined exception handlers (try-catch replacements) that are concise and neat. You can easily define your own reusable handlers to fit policies of your project.

Example:

System.out.println(Exceptions.log().get(() -> "test".substring(5)).orElse("fallback"));

The above is equivalent to the following try-catch code:

Logger logger = LoggerFactory.getLogger(...);
String result;
try {
    result = "test".substring(5);
} catch (Throwable exception) {
    logger.error("Caught exception", exception);
    result = "fallback";
}
System.out.println(result);

There's more to NoException. Read on.

Download

Get NoException from Maven Central:

<dependency>
    <groupId>com.machinezoo.noexception</groupId>
    <artifactId>noexception</artifactId>
    <version>1.1.0</version>
</dependency>

Or get the source code.

Why?

Application code is often littered with boilerplate try-catch blocks. Verbosity of try-catch encourages developers to avoid it and to propagate exceptions instead. Notable recurring examples include fallbacks, callbacks, event/job loops, executors, and lambdas.

// Fallbacks: Exception severity escalated where logging and fallback would suffice
important.add(unimportant());

// Callbacks: Exception erroneously propagated to unrelated code
if (callback != null)
    callback.run();

// Event/job loops: Exception kills the whole loop including unrelated jobs
for (Job job : jobs)
    job.run();

// Executors: Exception lost in Future that is not awaited
executor.submit(() -> Files.write("file", data));

// Lambdas: Compiler error due to checked exception
process(() -> Files.readAllLines(at));

Tutorial

NoException defines a set of reusable checked and unchecked exception handlers (or exception blocks) and lets you easily define your own. NoException's handlers are concise, lambda-friendly, and thoroughly tested. They can be used to ensure correct and consistent exception handling throughout your project.

Catch-all handlers

If you just want to get rid of all exceptions, use Exceptions.log().

String test = null;
Exceptions.log().run(() -> System.out.println("This is " + test));

If exception is thrown, Exceptions.log() will catch it, log it via SLF4J, and it will return normally.

Fallbacks

To return a value, call get(Supplier) instead of run(Runnable). It returns standard Optional, which lets you specify fallback value via orElse(T) or fallback supplier via orElseGet(Supplier).

System.out.println(Exceptions.log().get(() -> "test".substring(5)).orElse("fallback"));

Checked exceptions

You can avoid checked exception nuisance, especially on lambdas, by either wrapping checked exceptions in unchecked ones using Exceptions.wrap() or by sneaking them past compiler checks using Exceptions.sneak(), which works the same way as lombok's @SneakyThrows.

byte[] utf = Exceptions.sneak().get(() -> "test".getBytes("UTF-8"));

Above code can still throw checked exceptions, but the compiler believes it will not.

If you want to also catch the checked exceptions, combine checked and unchecked exception handlers:

static final List<String> lines = Exceptions.log()
    .get(Exceptions.sneak().supplier(() -> Files.readAllLines("test.txt")))
    .orElse(Collections.emptyList());

Functional interfaces

To handle exceptions from functional interfaces with parameters, first wrap the functional interface and then apply its parameters.

Function<String, String> hello = x -> "Hello " + x;
System.out.println(Exceptions.log().function(hello).apply(null).orElse("Who?"));

Method function(Function) above returns OptionalFunction, a special functional interface defined by NoException that returns Optional when executed. In order to pass it to a method that expects standard Function, you can call orElse(T) method on the OptionalFunction.

Function<Object, String> stringer = x -> "[" + x.toString() + "]";
Function<Object, String> safe = Exceptions.log().function(stringer).orElse("oops");
System.out.println(safe.apply(null));

Predefined handlers

Class Exceptions provides several predefined exception handlers:

Custom handlers

To create custom exception handler, override handle(Throwable) method of ExceptionHandler.

public class ExceptionCounter extends ExceptionHandler {
    private long count;
    @Override public synchronized boolean handle(Throwable exception) {
        ++count;
        return true;
    }
    public synchronized long report() {
        return count;
    }
}
public class ExceptionPolicy {
    private static final ExceptionCounter counter = new ExceptionCounter();
    public static ExceptionCounter count() {
        return counter;
    }
}

And use it anywhere:

ExceptionPolicy.count().run(() -> oftenFailingCode());
System.out.println(ExceptionPolicy.count().report());

You can also define custom checked exception policy by overriding handle(Exception) method of CheckedExceptionHandler, but you are usually better off supplying custom wrapper to Exceptions.wrap(Function).

public class ExceptionPolicy {
    public static CheckedExceptionHandler wrap(String message) {
        return Exceptions.wrap(e -> new RuntimeException(message, e));
    }
}

// example usage
ExceptionPolicy.wrap("Failed to save the upload").run(() -> Files.write(path, data));

Configurator

You would normally use your IDE's auto-complete. This configurator is here only to help you understand the API. It shows canonical, idiomatic code.

String result = Exceptions.log().get(() -> /* ... */).orElse("fallback");

// multi-line example
String result = Exceptions.log().get(() -> {
    // ...
    return "result";
}).orElse("fallback");

See Exceptions.log(), ExceptionHandler.get(Supplier).

Supported functional interfaces

NoException supports all standard functional interfaces in Java. The following table links to javadoc for every combination of functional interface and implemented feature. Link is missing only where it does not make sense, for example when the functional interface returns void or it is not parameterless.

Throwing interface
e.g. ThrowingRunnable
Optional interface
e.g. OptionalSupplier
Catch-all wrapper
e.g. runnable(Runnable)
Catch-all runner
e.g. run(Runnable)
Checked exception wrapper
e.g. runnable(ThrowingRunnable)
Checked exception runner
e.g. run(ThrowingRunnable)
Runnable
void run()
ThrowingRunnableExceptionHandler.runnable(Runnable)ExceptionHandler.run(Runnable)CheckedExceptionHandler.runnable(ThrowingRunnable)CheckedExceptionHandler.run(ThrowingRunnable)
Supplier
T get()
ThrowingSupplierOptionalSupplierExceptionHandler.supplier(Supplier)ExceptionHandler.get(Supplier)CheckedExceptionHandler.supplier(ThrowingSupplier)CheckedExceptionHandler.get(ThrowingSupplier)
IntSupplier
int getAsInt()
ThrowingIntSupplierOptionalIntSupplierExceptionHandler.fromIntSupplier(IntSupplier)ExceptionHandler.getAsInt(IntSupplier)CheckedExceptionHandler.fromIntSupplier(ThrowingIntSupplier)CheckedExceptionHandler.getAsInt(ThrowingIntSupplier)
LongSupplier
long getAsLong()
ThrowingLongSupplierOptionalLongSupplierExceptionHandler.fromLongSupplier(LongSupplier)ExceptionHandler.getAsLong(LongSupplier)CheckedExceptionHandler.fromLongSupplier(ThrowingLongSupplier)CheckedExceptionHandler.getAsLong(ThrowingLongSupplier)
DoubleSupplier
double getAsDouble()
ThrowingDoubleSupplierOptionalDoubleSupplierExceptionHandler.fromDoubleSupplier(DoubleSupplier)ExceptionHandler.getAsDouble(DoubleSupplier)CheckedExceptionHandler.fromDoubleSupplier(ThrowingDoubleSupplier)CheckedExceptionHandler.getAsDouble(ThrowingDoubleSupplier)
BooleanSupplier
boolean getAsBoolean()
ThrowingBooleanSupplierOptionalBooleanSupplierExceptionHandler.fromBooleanSupplier(BooleanSupplier)ExceptionHandler.getAsBoolean(BooleanSupplier)CheckedExceptionHandler.fromBooleanSupplier(ThrowingBooleanSupplier)CheckedExceptionHandler.getAsBoolean(ThrowingBooleanSupplier)
Predicate
boolean test(T t)
ThrowingPredicateOptionalPredicateExceptionHandler.predicate(Predicate)CheckedExceptionHandler.predicate(ThrowingPredicate)
IntPredicate
boolean test(int v)
ThrowingIntPredicateOptionalIntPredicateExceptionHandler.fromIntPredicate(IntPredicate)CheckedExceptionHandler.fromIntPredicate(ThrowingIntPredicate)
LongPredicate
boolean test(long v)
ThrowingLongPredicateOptionalLongPredicateExceptionHandler.fromLongPredicate(LongPredicate)CheckedExceptionHandler.fromLongPredicate(ThrowingLongPredicate)
DoublePredicate
boolean test(double v)
ThrowingDoublePredicateOptionalDoublePredicateExceptionHandler.fromDoublePredicate(DoublePredicate)CheckedExceptionHandler.fromDoublePredicate(ThrowingDoublePredicate)
Consumer
void accept(T t)
ThrowingConsumerExceptionHandler.consumer(Consumer)CheckedExceptionHandler.consumer(ThrowingConsumer)
IntConsumer
void accept(int v)
ThrowingIntConsumerExceptionHandler.fromIntConsumer(IntConsumer)CheckedExceptionHandler.fromIntConsumer(ThrowingIntConsumer)
LongConsumer
void accept(long v)
ThrowingLongConsumerExceptionHandler.fromLongConsumer(LongConsumer)CheckedExceptionHandler.fromLongConsumer(ThrowingLongConsumer)
DoubleConsumer
void accept(double v)
ThrowingDoubleConsumerExceptionHandler.fromDoubleConsumer(DoubleConsumer)CheckedExceptionHandler.fromDoubleConsumer(ThrowingDoubleConsumer)
BiConsumer
void accept(T t, U u)
ThrowingBiConsumerExceptionHandler.fromBiConsumer(BiConsumer)CheckedExceptionHandler.fromBiConsumer(ThrowingBiConsumer)
ObjIntConsumer
void accept(T t, int v)
ThrowingObjIntConsumerExceptionHandler.fromObjIntConsumer(ObjIntConsumer)CheckedExceptionHandler.fromObjIntConsumer(ThrowingObjIntConsumer)
ObjLongConsumer
void accept(T t, long v)
ThrowingObjLongConsumerExceptionHandler.fromObjLongConsumer(ObjLongConsumer)CheckedExceptionHandler.fromObjLongConsumer(ThrowingObjLongConsumer)
ObjDoubleConsumer
void accept(T t, double v)
ThrowingObjDoubleConsumerExceptionHandler.fromObjDoubleConsumer(ObjDoubleConsumer)CheckedExceptionHandler.fromObjDoubleConsumer(ThrowingObjDoubleConsumer)
UnaryOperator
T apply(T t)
ThrowingUnaryOperatorOptionalUnaryOperatorExceptionHandler.fromUnaryOperator(UnaryOperator)CheckedExceptionHandler.fromUnaryOperator(ThrowingUnaryOperator)
IntUnaryOperator
int applyAsInt(int v)
ThrowingIntUnaryOperatorOptionalIntUnaryOperatorExceptionHandler.fromIntUnaryOperator(IntUnaryOperator)CheckedExceptionHandler.fromIntUnaryOperator(ThrowingIntUnaryOperator)
LongUnaryOperator
long applyAsLong(long v)
ThrowingLongUnaryOperatorOptionalLongUnaryOperatorExceptionHandler.fromLongUnaryOperator(LongUnaryOperator)CheckedExceptionHandler.fromLongUnaryOperator(ThrowingLongUnaryOperator)
DoubleUnaryOperator
double applyAsDouble(double v)
ThrowingDoubleUnaryOperatorOptionalDoubleUnaryOperatorExceptionHandler.fromDoubleUnaryOperator(DoubleUnaryOperator)CheckedExceptionHandler.fromDoubleUnaryOperator(ThrowingDoubleUnaryOperator)
BinaryOperator
T apply(T l, R r)
ThrowingBinaryOperatorOptionalBinaryOperatorExceptionHandler.fromBinaryOperator(BinaryOperator)CheckedExceptionHandler.fromBinaryOperator(ThrowingBinaryOperator)
IntBinaryOperator
int applyAsInt(int l, int r)
ThrowingIntBinaryOperatorOptionalIntBinaryOperatorExceptionHandler.fromIntBinaryOperator(IntBinaryOperator)CheckedExceptionHandler.fromIntBinaryOperator(ThrowingIntBinaryOperator)
LongBinaryOperator
long applyAsLong(long l, long r)
ThrowingLongBinaryOperatorOptionalLongBinaryOperatorExceptionHandler.fromLongBinaryOperator(LongBinaryOperator)CheckedExceptionHandler.fromLongBinaryOperator(ThrowingLongBinaryOperator)
DoubleBinaryOperator
double applyAsDouble(double l, double r)
ThrowingDoubleBinaryOperatorOptionalDoubleBinaryOperatorExceptionHandler.fromDoubleBinaryOperator(DoubleBinaryOperator)CheckedExceptionHandler.fromDoubleBinaryOperator(ThrowingDoubleBinaryOperator)
Function
R apply(T t)
ThrowingFunctionOptionalFunctionExceptionHandler.function(Function)CheckedExceptionHandler.function(ThrowingFunction)
IntFunction
R apply(int v)
ThrowingIntFunctionOptionalIntFunctionExceptionHandler.fromIntFunction(IntFunction)CheckedExceptionHandler.fromIntFunction(ThrowingIntFunction)
LongFunction
R apply(long v)
ThrowingLongFunctionOptionalLongFunctionExceptionHandler.fromLongFunction(LongFunction)CheckedExceptionHandler.fromLongFunction(ThrowingLongFunction)
DoubleFunction
R apply(double v)
ThrowingDoubleFunctionOptionalDoubleFunctionExceptionHandler.fromDoubleFunction(DoubleFunction)CheckedExceptionHandler.fromDoubleFunction(ThrowingDoubleFunction)
ToIntFunction
int applyAsInt(T t)
ThrowingToIntFunctionOptionalToIntFunctionExceptionHandler.fromToIntFunction(ToIntFunction)CheckedExceptionHandler.fromToIntFunction(ThrowingToIntFunction)
ToLongFunction
long applyAsLong(T t)
ThrowingToLongFunctionOptionalToLongFunctionExceptionHandler.fromToLongFunction(ToLongFunction)CheckedExceptionHandler.fromToLongFunction(ThrowingToLongFunction)
ToDoubleFunction
double applyAsDouble(T t)
ThrowingToDoubleFunctionOptionalToDoubleFunctionExceptionHandler.fromToDoubleFunction(ToDoubleFunction)CheckedExceptionHandler.fromToDoubleFunction(ThrowingToDoubleFunction)
IntToLongFunction
long applyAsLong(int v)
ThrowingIntToLongFunctionOptionalIntToLongFunctionExceptionHandler.fromIntToLongFunction(IntToLongFunction)CheckedExceptionHandler.fromIntToLongFunction(ThrowingIntToLongFunction)
IntToDoubleFunction
double applyAsDouble(int v)
ThrowingIntToDoubleFunctionOptionalIntToDoubleFunctionExceptionHandler.fromIntToDoubleFunction(IntToDoubleFunction)CheckedExceptionHandler.fromIntToDoubleFunction(ThrowingIntToDoubleFunction)
LongToIntFunction
int applyAsInt(long v)
ThrowingLongToIntFunctionOptionalLongToIntFunctionExceptionHandler.fromLongToIntFunction(LongToIntFunction)CheckedExceptionHandler.fromLongToIntFunction(ThrowingLongToIntFunction)
LongToDoubleFunction
double applyAsDouble(long v)
ThrowingLongToDoubleFunctionOptionalLongToDoubleFunctionExceptionHandler.fromLongToDoubleFunction(LongToDoubleFunction)CheckedExceptionHandler.fromLongToDoubleFunction(ThrowingLongToDoubleFunction)
DoubleToIntFunction
int applyAsInt(double v)
ThrowingDoubleToIntFunctionOptionalDoubleToIntFunctionExceptionHandler.fromDoubleToIntFunction(DoubleToIntFunction)CheckedExceptionHandler.fromDoubleToIntFunction(ThrowingDoubleToIntFunction)
DoubleToLongFunction
long applyAsLong(double v)
ThrowingDoubleToLongFunctionOptionalDoubleToLongFunctionExceptionHandler.fromDoubleToLongFunction(DoubleToLongFunction)CheckedExceptionHandler.fromDoubleToLongFunction(ThrowingDoubleToLongFunction)
BiFunction
R apply(T t, U u)
ThrowingBiFunctionOptionalBiFunctionExceptionHandler.fromBiFunction(BiFunction)CheckedExceptionHandler.fromBiFunction(ThrowingBiFunction)
ToIntBiFunction
int applyAsInt(T t, U u)
ThrowingToIntBiFunctionOptionalToIntBiFunctionExceptionHandler.fromToIntBiFunction(ToIntBiFunction)CheckedExceptionHandler.fromToIntBiFunction(ThrowingToIntBiFunction)
ToLongBiFunction
long applyAsLong(T t, U u)
ThrowingToLongBiFunctionOptionalToLongBiFunctionExceptionHandler.fromToLongBiFunction(ToLongBiFunction)CheckedExceptionHandler.fromToLongBiFunction(ThrowingToLongBiFunction)
ToDoubleBiFunction
double applyAsDouble(T t, U u)
ThrowingToDoubleBiFunctionOptionalToDoubleBiFunctionExceptionHandler.fromToDoubleBiFunction(ToDoubleBiFunction)CheckedExceptionHandler.fromToDoubleBiFunction(ThrowingToDoubleBiFunction)
Comparator
int compare(T l, T r)
ThrowingComparatorOptionalComparatorExceptionHandler.comparator(Comparator)CheckedExceptionHandler.comparator(ThrowingComparator)

Alternatives

NoException was developed shortly after Java 8 launch, but I kept it as an internal project. By the time I got around to publishing it, there were several other projects solving the same problem. I am nevertheless pleasantly surprised that NoException is a clean superset of functionality in the other projects.

NoException fge jOOL StreamUnthrower Liebenberg Durian Faux Pas
Logging handler yes no no no rethrowing yes no
Silent handler yes no no no yes yes no
Custom handler yes no yes no yes yes no
Wrapped rethrow yes yes yes no no yes no
Sneaky rethrow yes yes yes yes yes no yes
Wraps lambda yes yes yes no yes yes yes
Runs lambda yes no no yes no yes no
Optional return yes custom no no no fallback only no
Supported interfaces all all all custom all few some
Tutorial yes yes yes yes yes sort of yes
Javadoc yes no yes no yes yes no
Maven Central yes yes yes no yes yes yes

Feedback

NoException was developed by Robert Važan. If you have any questions, email me. If you have any suggestions, submit an issue or just fork the source code and submit a pull request.