{"record":{"id":"4c719608a74e113f","repo":"apache/beam","slug":"completionexception","errorCode":null,"errorMessage":"CompletionException","messagePattern":"CompletionException","errorType":"exception","errorClass":"java.util.concurrent.CompletionException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/util/MoreFutures.java","lineNumber":105,"sourceCode":"   */\n  public static boolean isCancelled(CompletionStage<?> future) {\n    return future.toCompletableFuture().isCancelled();\n  }\n\n  /**\n   * Like {@link CompletableFuture#supplyAsync(Supplier)} but for {@link ThrowingSupplier}.\n   *\n   * <p>If the {@link ThrowingSupplier} throws an exception, the future completes exceptionally.\n   */\n  public static <T> CompletionStage<T> supplyAsync(\n      ThrowingSupplier<T> supplier, ExecutorService executorService) {\n    return CompletableFuture.supplyAsync(\n        () -> {\n          try {\n            return supplier.get();\n          } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n            throw new CompletionException(e);\n          } catch (OutOfMemoryError oom) {\n            throw oom;\n          } catch (Throwable t) {\n            throw new CompletionException(t);\n          }\n        },\n        executorService);\n  }\n\n  /**\n   * Shorthand for {@link #supplyAsync(ThrowingSupplier, ExecutorService)} using {@link\n   * ForkJoinPool#commonPool()}.\n   */\n  public static <T> CompletionStage<T> supplyAsync(ThrowingSupplier<T> supplier) {\n    return supplyAsync(supplier, ForkJoinPool.commonPool());\n  }\n\n  /**","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/util/MoreFutures.java#L87-L123","documentation":"MoreFutures.supplyAsync wraps any InterruptedException thrown by the supplier into java.util.concurrent.CompletionException (with the interrupt re-signaled on the thread). The future completes exceptionally with CompletionException, so callers joining/getting see this exception.","triggerScenarios":"A supplier passed to MoreFutures.supplyAsync throws InterruptedException while executing on the supplied ExecutorService (e.g. blocked I/O interrupted on shutdown).","commonSituations":"Executor shutdownNow() interrupting in-flight async work; pipeline teardown cancelling futures; blocking calls inside async suppliers interrupted by timeouts.","solutions":["Catch CompletionException from future.get()/join() and inspect getCause() for InterruptedException","Avoid interruptible blocking work in async suppliers, or handle interruption gracefully","Ensure the executor is not shut down while work is expected to complete","Restore/propagate the interrupt flag if you catch InterruptedException yourself"],"exampleFix":"// before\nString v = moreFuture.join();\n// after\ntry { String v = moreFuture.join(); }\ncatch (CompletionException e) {\n  if (e.getCause() instanceof InterruptedException) { Thread.currentThread().interrupt(); }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { v = future.get(); } catch (ExecutionException e) { if (e.getCause() instanceof InterruptedException) { Thread.currentThread().interrupt(); } throw e; }","preventionTips":["Don't interrupt executors while async work is in flight","Avoid long interruptible blocking calls inside suppliers","Re-establish the interrupt flag when handling InterruptedException"],"tags":["java","concurrency","futures","interrupt"],"backgroundTag":"thread-interrupted","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}