Futures { public static <T> CompletableFuture<T> failedFuture( Throwable error ) { CompletableFuture<T> result = new CompletableFuture<>(); result.completeExceptionally( error ); return result; } private  Futures(); @SuppressWarnings( "unchecked" ) static CompletableFuture<T> completedWithNull(); static CompletableFuture<T> completeWithNullIfNoError( CompletableFuture<T> future, Throwable error ); static CompletionStage<T> asCompletionStage( io.netty.util.concurrent.Future<T> future ); static CompletionStage<T> asCompletionStage( io.netty.util.concurrent.Future<T> future, CompletableFuture<T> result ); static CompletableFuture<T> failedFuture( Throwable error ); static V blockingGet( CompletionStage<V> stage ); static V blockingGet( CompletionStage<V> stage, Runnable interruptHandler ); static T getNow( CompletionStage<T> stage ); static Throwable completionExceptionCause( Throwable error ); static CompletionException asCompletionException( Throwable error ); static CompletionException combineErrors( Throwable error1, Throwable error2 ); @SuppressWarnings( "ThrowableNotThrown" ) static CompletableFuture<T> onErrorContinue( CompletableFuture<T> future, Throwable errorRecorder,
            Function<Throwable,? extends CompletionStage<T>> onErrorAction );  }
@Test void shouldCreateFailedFutureWithUncheckedException() throws Exception { RuntimeException error = new RuntimeException( "Hello" ); CompletableFuture<Object> future = Futures.failedFuture( error ).toCompletableFuture(); assertTrue( future.isCompletedExceptionally() ); ExecutionException e = assertThrows( ExecutionException.class, future::get ); assertEquals( error, e.getCause() ); }
@Test void shouldCreateFailedFutureWithCheckedException() throws Exception { IOException error = new IOException( "Hello" ); CompletableFuture<Object> future = Futures.failedFuture( error ).toCompletableFuture(); assertTrue( future.isCompletedExceptionally() ); ExecutionException e = assertThrows( ExecutionException.class, future::get ); assertEquals( error, e.getCause() ); }