Generated from at 3.0.0 2020-08-11T17:36:18Z

Exception Handling


Basic introduction (by example) to exception handling with functional interfaces from this library.


Each functional interface has the ability to customise exception handling. There are more than few methods to do that. It might be best to present them on one single example: LFunction.

Default behaviour

First, the actual method that need to be implemented is throwing Throwable:

R applyX(T a) throws Throwable;

This method is not intended to be used directly, because there is less exotic method to be called:

default R apply(T a) { ... }

This is what this method does: 1. Intercepts Throwable 2. Immediately rethrows errors. 3. Rethrows runtime exceptions. 4. Nests checked exceptions in NestedException.

Handling customization

Following possibilities can only be used for runtime exceptions and checked exceptions:

  1. There is -handlingApply- method that additionally takes argument HandlingInstructions. See HandlingInstructions and Handler
  2. There two -apply- methods that additionally takes reference to exception constructor with option to pass message arguments.
  3. There is -applyThen- that takes function that is supposed to transform exception into the originally expected value type.

So, in general there are 3 possibilities to handle exceptions:

  1. Instance methods that is just 'apply' with additional handling. To handle exceptions on per call basis.
  2. Instance methods that returns function that always does the exact handling every time. To create function that handles exceptions for all calls.
  3. Static method that takes function arguments, function instance, and handling argument.


Probably the most quick use of exception handling, provided that situation does not require actual handling of exception (and propagation of nested exception is enough) would be:

@Test public void oneLinePropagation() { LLongConsumer.tryAccept(300, Thread::sleep); }

For further examples lets confider a method and/or function that throw checked exceptions:

public static final LFunction<Integer, Integer> throwingAlways = LFunction.func(Example_ExceptionHandling_Test::throwingAlways); public static Integer throwingAlways(Integer i) throws CheckedException { throw new CheckedException("Something went wrong"); }

And here is an example with handling instructions:

@Test(expectedExceptions = DifferentRuntimeException.class) public void exampleHandling() { LFunction<Integer, Integer> function1 = throwingAlways.handling(h -> h .wrapIf(e -> e instanceof RuntimeException, RuntimeException::new) .wrapIf(pred(Has::cause).and(Is::notRuntime), DifferentSpecializedRuntimeException::new) .wrap(DifferentRuntimeException::new) ); function1.apply(0); }

Handling block can be empty. If so, then Nested exception will be produced for any exception except unchecked exceptions that can be freely propagated.

@Test(expectedExceptions = NestedException.class) public void exampleNoHandlingAtAll() { LFunction<Integer, Integer> function = throwingAlways.handling(h -> { }); function.apply(0); }

A more simpler examples:

@Test(expectedExceptions = DifferentRuntimeException.class) public void simpleExample() throws DifferentRuntimeException { throwingAlways.apply(0, DifferentRuntimeException::new); } @Test(expectedExceptions = DifferentRuntimeException.class, expectedExceptionsMessageRegExp = "message text") public void simpleExampleWithMessage() throws DifferentRuntimeException { throwingAlways.apply(0, DifferentRuntimeException::new, "message text"); }

Following examples shows the purpose of the static handling methods - one-line handling for any method call (assuming that there is a library function that covers the specific argument case).

@Test(expectedExceptions = NestedException.class) public void staticExamples() { LFunction.tryApply(0, Example_ExceptionHandling_Test::throwingAlways); } @Test(expectedExceptions = DifferentRuntimeException.class, expectedExceptionsMessageRegExp = "text message and param") public void staticExamples2() { LFunction.tryApply(0, Example_ExceptionHandling_Test::throwingAlways, DifferentRuntimeException::new, "text message and %s", "param"); }

Generated from at 3.0.0 2020-08-11T17:36:18Z