Skip to content

Commit eb45653

Browse files
committed
Add a VertxConnectionTest reproducing the flush before close on exception
Covers the fix at the connection layer: a write queued (unflushed) when a caught exception triggers the close must reach the channel before it closes, otherwise Netty's ChannelOutboundBuffer discards the unflushed entry. The test fails without the VertxHandler.exceptionCaught change and passes with it. Signed-off-by: Alexandru Salajan <alexandru17@gmail.com>
1 parent 213479e commit eb45653

1 file changed

Lines changed: 23 additions & 0 deletions

File tree

vertx-core/src/test/java/io/vertx/tests/net/VertxConnectionTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,4 +778,27 @@ public void testResumeWhenReadInProgress() {
778778
outbound = ch.readOutbound();
779779
assertSame(expected, outbound);
780780
}
781+
782+
@Test
783+
public void testFlushPendingWriteOnExceptionClose() {
784+
EmbeddedChannel ch = new EmbeddedChannel();
785+
ChannelPipeline pipeline = ch.pipeline();
786+
pipeline.addLast(VertxHandler.create(chctx -> new TestConnection(chctx)));
787+
TestConnection connection = (TestConnection) pipeline.get(VertxHandler.class).getConnection();
788+
connection.exceptionHandler(err -> {});
789+
// Queue a write without flushing it: this is the state produced when a response is written
790+
// while a read is in progress (e.g. an inbound codec failing mid-decode, which is how a
791+
// request-body decompression failure surfaces). The message sits in the channel outbound
792+
// buffer as an unflushed entry.
793+
Object response = new Object();
794+
connection.unsafeWrite(response, false);
795+
assertNull(ch.readOutbound());
796+
// The failure surfaces as a caught exception that asks the connection to close. The close
797+
// must flush the pending write before closing the channel, otherwise Netty's
798+
// ChannelOutboundBuffer discards the unflushed entry and the peer never sees the response.
799+
pipeline.fireExceptionCaught(new RuntimeException());
800+
ch.runPendingTasks();
801+
assertSame(response, ch.readOutbound());
802+
assertFalse(ch.isOpen());
803+
}
781804
}

0 commit comments

Comments
 (0)