CompletableFuture Chain (Monad)
One thing that i'd like to propose is to replace CompletableFuture with home-brewed builder class that wraps CompletableFuture but will have more 'easy to read' interface. It would be something like this:

class FutureBuilder {

/**
 * Wrapped 'completable future' instance
 */
CompletableFuture future;

...
public FutureBuilder execute(Function&lt;...&gt; task) {...}
public FutureBuilder whenComplete(Consumer&lt;Report&gt; handler) {...}
public FutureBuilder whenFail(BiComsumer&lt;Report, Throwable&gt; handler) {...}
...

/**
 * This method should be called at the end to meet interface requirements
 */
public CompletableFuture build() {
      return future;
}
...
}


So, it may be used in next way:

public CompletableFuture&lt;Result&gt; handler(final RunnerJob job) {
   return new FutureBuilder ()
              .execute(bArr -&gt; this.module2.function2(bArr, job))
              .execute(metrics -&gt; this.module3.function3(metrics, job))
              .whenComplete(r-&gt; uilder().setResult(r).build())
              .whenFail((r, e) -&gt; { 
                   this.module4.function4(r, job);
                   return builder().setErrorMessage(e.getMessage()).build();
              })
              .build(); 
}


I hope that is you are looking for.