From fae36671b6aa76d56ca1cb48ebeb90a01de4799e Mon Sep 17 00:00:00 2001 From: graemerocher Date: Fri, 22 Apr 2022 11:57:11 +0200 Subject: [PATCH] Ignore unrecoverable ClosedChannelException errors --- .../http/server/netty/HttpPipelineBuilder.java | 10 ++++++++++ .../http/server/netty/RoutingInBoundHandler.java | 10 +++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/http-server-netty/src/main/java/io/micronaut/http/server/netty/HttpPipelineBuilder.java b/http-server-netty/src/main/java/io/micronaut/http/server/netty/HttpPipelineBuilder.java index e37d32cfacc..4f1f0ae1477 100644 --- a/http-server-netty/src/main/java/io/micronaut/http/server/netty/HttpPipelineBuilder.java +++ b/http-server-netty/src/main/java/io/micronaut/http/server/netty/HttpPipelineBuilder.java @@ -353,6 +353,16 @@ private HttpToHttp2ConnectionHandler newHttpToHttp2ConnectionHandler() { */ void configureForAlpn() { pipeline.addLast(new ApplicationProtocolNegotiationHandler(server.getServerConfiguration().getFallbackProtocol()) { + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + if (routingInBoundHandler.isIgnorable(cause)) { + // just abandon ship, nothing can be done here to recover + ctx.close(); + } else { + super.exceptionCaught(ctx, cause); + } + } + @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof SslHandshakeCompletionEvent) { diff --git a/http-server-netty/src/main/java/io/micronaut/http/server/netty/RoutingInBoundHandler.java b/http-server-netty/src/main/java/io/micronaut/http/server/netty/RoutingInBoundHandler.java index 1a1d786c5ab..abd9438aa35 100644 --- a/http-server-netty/src/main/java/io/micronaut/http/server/netty/RoutingInBoundHandler.java +++ b/http-server-netty/src/main/java/io/micronaut/http/server/netty/RoutingInBoundHandler.java @@ -1419,7 +1419,15 @@ private ByteBuf encodeBodyAsByteBuf( return byteBuf; } - private boolean isIgnorable(Throwable cause) { + /** + * Is the exception ignorable by Micronaut. + * @param cause The cause + * @return True if it can be ignored. + */ + protected boolean isIgnorable(Throwable cause) { + if (cause instanceof ClosedChannelException || cause.getCause() instanceof ClosedChannelException) { + return true; + } String message = cause.getMessage(); return cause instanceof IOException && message != null && IGNORABLE_ERROR_MESSAGE.matcher(message).matches(); }