From d857f8dcb40618fefbe85411a16f9c7b42fb9882 Mon Sep 17 00:00:00 2001 From: Jerry Lee Date: Sun, 2 Jun 2024 17:24:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20report=20exception=20info=20of=20peek?= =?UTF-8?q?=20action,=20errors=20should=20never=20pass=20silently=20?= =?UTF-8?q?=F0=9F=92=A3=20=F0=9F=91=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cffu/CompletableFutureUtils.java | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java b/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java index 6d1db59b..20832561 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java +++ b/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java @@ -10,6 +10,8 @@ import org.jetbrains.annotations.Contract; import javax.annotation.ParametersAreNonnullByDefault; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -1252,8 +1254,8 @@ public static CompletableFuture applyToEitherSuccessAsync( * Peeks the result by executing the given action when given stage completes, returns the given stage. *

* When the given stage is complete, the given action is invoked with the result (or {@code null} if none) - * and the exception (or {@code null} if none) of given stage as arguments. - * Whether the supplied action throws an exception or not, do NOT affect this cffu. + * and the exception (or {@code null} if none) of given stage as arguments. Whether the supplied action + * throws an exception or not, do NOT affect the given CompletableFuture. *

* Unlike method {@link CompletionStage#handle handle} and like method * {@link CompletionStage#whenComplete(BiConsumer) whenComplete}, @@ -1269,7 +1271,7 @@ C peek(C cf, BiConsumer action) { requireNonNull(cf, "cf is null"); requireNonNull(action, "action is null"); - cf.whenComplete(action); + cf.whenComplete(action).exceptionally(CompletableFutureUtils::reportExceptionInfoOfPeekAction); return cf; } @@ -1279,8 +1281,8 @@ C peek(C cf, BiConsumer action) { * returns the given stage. *

* When the given stage is complete, the given action is invoked with the result (or {@code null} if none) - * and the exception (or {@code null} if none) of given stage as arguments. - * Whether the supplied action throws an exception or not, do NOT affect this cffu. + * and the exception (or {@code null} if none) of given stage as arguments. Whether the supplied action + * throws an exception or not, do NOT affect the given CompletableFuture. *

* Unlike method {@link CompletionStage#handle handle} and like method * {@link CompletionStage#whenComplete(BiConsumer) whenComplete}, @@ -1301,8 +1303,8 @@ C peekAsync(C cf, BiConsumer action) { * executes the given action using the supplied Executor, returns the given stage. *

* When the given stage is complete, the given action is invoked with the result (or {@code null} if none) - * and the exception (or {@code null} if none) of given stage as arguments. - * Whether the supplied action throws an exception or not, do NOT affect this cffu. + * and the exception (or {@code null} if none) of given stage as arguments. Whether the supplied action + * throws an exception or not, do NOT affect the given CompletableFuture. *

* Unlike method {@link CompletionStage#handle handle} and like method * {@link CompletionStage#whenComplete(BiConsumer) whenComplete}, @@ -1319,10 +1321,22 @@ C peekAsync(C cf, BiConsumer action, Executor exec requireNonNull(action, "action is null"); requireNonNull(executor, "executor is null"); - cf.whenCompleteAsync(action, executor); + cf.whenCompleteAsync(action, executor).exceptionally(CompletableFutureUtils::reportExceptionInfoOfPeekAction); return cf; } + @Nullable + private static T reportExceptionInfoOfPeekAction(Throwable ex) { + StringWriter sw = new StringWriter(4096); + PrintWriter writer = new PrintWriter(sw); + + writer.println("Unexpected exception occurred in the action of peek:"); + ex.printStackTrace(writer); + + System.err.println(sw); + return null; + } + //////////////////////////////////////////////////////////////////////////////// //# Backport CF static methods + related enhanced methods // compatibility for low Java versions