From eee248ec73564e1b3be1126dc984233e87602ba6 Mon Sep 17 00:00:00 2001 From: zhanglangning Date: Tue, 11 Aug 2026 01:39:47 +0800 Subject: [PATCH] Report AsyncFile handler failures to context --- .../vertx/core/file/impl/AsyncFileImpl.java | 1 + .../io/vertx/tests/file/FileSystemTest.java | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/vertx-core/src/main/java/io/vertx/core/file/impl/AsyncFileImpl.java b/vertx-core/src/main/java/io/vertx/core/file/impl/AsyncFileImpl.java index b0e06fa36e9..b032ee43313 100644 --- a/vertx-core/src/main/java/io/vertx/core/file/impl/AsyncFileImpl.java +++ b/vertx-core/src/main/java/io/vertx/core/file/impl/AsyncFileImpl.java @@ -103,6 +103,7 @@ public class AsyncFileImpl implements AsyncFile { } this.context = context; this.queue = new InboundBuffer<>(context, 0); + queue.exceptionHandler(context::reportException); queue.handler(buff -> { if (buff.length() > 0) { handleBuffer(buff); diff --git a/vertx-core/src/test/java/io/vertx/tests/file/FileSystemTest.java b/vertx-core/src/test/java/io/vertx/tests/file/FileSystemTest.java index bd35fe7b7e3..c0b822a7cf4 100644 --- a/vertx-core/src/test/java/io/vertx/tests/file/FileSystemTest.java +++ b/vertx-core/src/test/java/io/vertx/tests/file/FileSystemTest.java @@ -21,6 +21,8 @@ import io.vertx.core.internal.buffer.BufferInternal; import io.vertx.core.file.impl.AsyncFileImpl; import io.vertx.core.impl.Utils; +import io.vertx.core.internal.ContextInternal; +import io.vertx.core.internal.VertxInternal; import io.vertx.core.json.JsonObject; import io.vertx.core.streams.ReadStream; import io.vertx.test.core.TestUtils; @@ -38,6 +40,7 @@ import java.nio.channels.OverlappingFileLockException; import java.nio.file.*; import java.nio.file.attribute.*; +import java.util.ArrayList; import java.util.EnumSet; import java.util.HashSet; import java.util.List; @@ -2314,4 +2317,36 @@ public void testClosedAsyncFileSetNullHandler() throws Exception { asyncFile.drainHandler(null); asyncFile.endHandler(null); } + + @Test + public void testAsyncFileHandlerFailuresAreReportedToContext() throws Exception { + String fileName = "file.txt"; + createFileWithJunk(fileName, 100); + RuntimeException dataFailure = new RuntimeException("data"); + RuntimeException endFailure = new RuntimeException("end"); + List reported = new ArrayList<>(); + AtomicInteger fileExceptions = new AtomicInteger(); + AtomicReference closeFailure = new AtomicReference<>(); + CountDownLatch closed = new CountDownLatch(1); + ContextInternal context = ((VertxInternal) vertx).getOrCreateContext(); + context.runOnContext(ignored -> { + AsyncFile file = vertx.fileSystem().openBlocking(testDir + pathSep + fileName, new OpenOptions()); + context.exceptionHandler(reported::add); + file.exceptionHandler(ignored2 -> fileExceptions.incrementAndGet()); + file.endHandler(ignored2 -> { + file.close().onComplete(ar -> { + closeFailure.set(ar.cause()); + closed.countDown(); + }); + throw endFailure; + }); + file.handler(buffer -> { + throw dataFailure; + }); + }); + TestUtils.awaitLatch(closed); + Assert.assertNull(closeFailure.get()); + Assert.assertEquals(List.of(dataFailure, endFailure), reported); + Assert.assertEquals(0, fileExceptions.get()); + } }