Class CompletableFutureExtensions

java.lang.Object
nl.pim16aap2.animatedarchitecture.core.util.CompletableFutureExtensions

public final class CompletableFutureExtensions extends Object
Contains extensions for the CompletableFuture class.

To use these extensions, you need to annotate the class in which you want to use them with @ExtensionMethod(CompletableFutureExtensions.class).

For example, if you want to use the withExceptionContext(CompletableFuture, Supplier) method in a class called MyClass to add context to exceptions thrown by a future, you would do the following:

@ExtensionMethod(CompletableFutureExtensions.class)
public class MyClass {
   public CompletableFuture<MyEntity> findById(long id) {
       return CompletableFuture
           .supplyAsync(() -> repository.findById(id))
           .withExceptionContext(() -> "Failed to find entity with id " + id);
       }
   }
  • Method Details

    • withExceptionContext

      public static <T> CompletableFuture<T> withExceptionContext(CompletableFuture<T> future, Supplier<String> context)
      Returns a future that either completes with the result of the original future or exceptionally with a new exception that includes the provided context.

      In short, this method throws a new exception with the provided context if the original future completes exceptionally.

      One important thing to note is that supplier is only called when the future completes. So supplier that depends on some state might append different context than expected. This is even true for 'simple' suppliers such as Object::toString may depend on the state of the object.

      Type Parameters:
      T - The type of the future.
      Parameters:
      future - The original future.
      context - The context to include in the exception.
      Returns:
      A future that completes with the result of the original future or exceptionally with a new exception that includes the provided context.
    • withExceptionContext

      @FormatMethod public static <T> CompletableFuture<T> withExceptionContext(CompletableFuture<T> future, @FormatString String contextFormat, @Nullable Object @Nullable ... args)
      Shortcut for withExceptionContext(CompletableFuture, Supplier) that formats the context using the provided format string and arguments.

      Beware of the same caveats as mentioned in withExceptionContext(CompletableFuture, Supplier).

      Type Parameters:
      T - The type of the future.
      Parameters:
      future - The original future.
      contextFormat - The format string for the context.
      args - The arguments for the format string.
      Returns:
      A future that completes with the result of the original future or exceptionally with a new exception that includes the provided context.
    • handleExceptional

      public static void handleExceptional(CompletableFuture<?> future, Consumer<Throwable> handler)
      Attaches a handler to the provided future to handle exceptions using the provided handler.

      This method allows specifying a custom handler for exceptions. The original future's completion state is unaffected - this method only adds a handler for exceptions.

      This method is intended to be used as a terminal operation in a chain of future operations.

      Example usage when using Lombok's @ExtensionMethod annotation:

      CompletableFuture<Response> future = client.sendRequest();
      future.handleExceptional(ex -> log.atError().withCause(ex).log("Request failed!"));
      
      Parameters:
      future - The future to monitor for exceptions.
      handler - The function to call with any exception that occurs in the future.
    • logExceptions

      public static void logExceptions(CompletableFuture<?> future)
      Attaches a handler to the provided future that logs any exceptions using the default logger.

      This is a convenience method that logs exceptions at WARNING level with the message "Exception occurred in CompletableFuture!". For custom (logging) behavior, use handleExceptional(CompletableFuture, Consumer) instead.

      This method is intended to be used as a terminal operation in a chain of future operations.

      Example usage when using Lombok's @ExtensionMethod annotation:

      CompletableFuture<User> future = userService.findUser(userId);
      future.logExceptions();
      
      Parameters:
      future - The future to monitor for exceptions.