diff --git a/computation/src/main/java/com/powsybl/computation/CompletableFutureTask.java b/computation/src/main/java/com/powsybl/computation/CompletableFutureTask.java index 806edd34f79..17530b5b420 100644 --- a/computation/src/main/java/com/powsybl/computation/CompletableFutureTask.java +++ b/computation/src/main/java/com/powsybl/computation/CompletableFutureTask.java @@ -45,11 +45,13 @@ public void run() { future.run(); try { complete(future.get()); + } catch (ExecutionException exc) { + completeExceptionally(exc.getCause()); } catch (InterruptedException exc) { Thread.currentThread().interrupt(); completeExceptionally(exc); } catch (Exception exc) { - completeExceptionally(exc.getCause()); + completeExceptionally(exc); } } diff --git a/computation/src/test/java/com/powsybl/computation/CompletableFutureTaskTest.java b/computation/src/test/java/com/powsybl/computation/CompletableFutureTaskTest.java index a97d6e69dd4..3e2c191ea40 100644 --- a/computation/src/test/java/com/powsybl/computation/CompletableFutureTaskTest.java +++ b/computation/src/test/java/com/powsybl/computation/CompletableFutureTaskTest.java @@ -40,10 +40,39 @@ private static List executors() { Executors.newSingleThreadExecutor(), Executors.newCachedThreadPool(), Executors.newWorkStealingPool(), + new MyTestExecutorWithException(), ForkJoinPool.commonPool() ); } + // Very basic executor that spawns a new thread + // and allows to wait for the end of the command. + // It just keeps an exception to be able to assert it. + // You should use it to launch only one command + // because it has just one latch and one exception + private static class MyTestExecutorWithException implements Executor { + + Exception exception = null; + CountDownLatch waitForDone; + + @Override + public void execute(Runnable command) { + (new Thread() { + @Override + public void run() { + waitForDone = new CountDownLatch(1); + try { + command.run(); + } catch (Exception e) { + MyTestExecutorWithException.this.exception = e; + } finally { + waitForDone.countDown(); + } + } + }).start(); + } + } + @ParameterizedTest @MethodSource("parameters") void whenSupplyObjectThenReturnIt(Executor executor) throws Exception { @@ -125,6 +154,10 @@ private void testEffectiveInterrupt(boolean addDependant, Executor executor) thr //Second call to cancel should return false cancelled = task.cancel(true); assertFalse(cancelled); + if (executor instanceof MyTestExecutorWithException myTestExecutor) { + myTestExecutor.waitForDone.await(); + assertNull(myTestExecutor.exception); + } } @ParameterizedTest