Netty - An exceptionCaught() event was fired, and it reached at the tail of the pipeline
Asked Answered
L

2

7

I got this warning in my log:

Nov 02, 2016 12:07:20 AM io.netty.channel.DefaultChannelPipeline onUnhandledInboundException
WARNUNG: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
java.util.concurrent.TimeoutException

That are my ChannelHandlers:

@Override
public void initChannel(SocketChannel ch) throws Exception {
    ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
    ch.pipeline().addLast(new TimeoutHandler(TIME_OUT_SECONDS));
    ch.pipeline().addLast(new ServerCommunicationHandler(messageHandler));
}

My TimeoutHandler throws a TimeoutException if there was no read for the last 15 seconds. And in my last handler, the ServerCommunicationHandler, i have overridden the exeptionCaught function:

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
    ctx.close();
}

So if i understand right, i do not rethrow the exception to the end of the pipeline, because my last handler processes the exception correctly, doesn't it?

Why do i get this warning?

I use Netty 4.1.6.Final

Lon answered 1/11, 2016 at 23:20 Comment(0)
G
4

This can be caused by your TimeoutHandler throwing the TimeoutException after the channel has been closed. It can happen because once a channel is closed all the ChannelHandlers will be removed (unregistered), but the ChannelHandlerContext still has a reference to the pipeline, so if you close a channel and then fire an event on the ctx there won't be any handlers to intercept the event.

I was able to recreate the error you see by writing a simple/broken TimeoutHandler:

@RequiredArgsConstructor
private static class TimeoutHandler extends ChannelInboundHandlerAdapter {
    private final int timeoutSeconds;

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        ctx.executor().schedule(
                // This exception can still be fired once the channel is closed and all handlers removed
                () -> ctx.fireExceptionCaught(new TimeoutException()), 
                timeoutSeconds, TimeUnit.SECONDS);
        super.channelRegistered(ctx);
    }
}

Have you considered using the Netty ReadTimeoutHandler instead of writing your own?

If you really want to write your own, make sure you are canceling your timer when the channel goes inactive. You can see how IdleStateHandler does this.

Gardal answered 2/11, 2016 at 15:19 Comment(1)
Thanks for your answer. I've implemented my timeout handler to notice timouts and if channel isn't open. I've debugged my program and yeah the channel was already closed when the exception was thrown. Thanks a lotLon
B
0

Maybe it's an exception thrown due to incomplete data received? My project also encountered this problem recently, because the received data code is GBK and I use utf8, so when intercepting the data in the corresponding location, I threw a subscript out of range error and caused this error.

screenshot of error message which is neither English nor printable with ISO-8859 charset

Brandy answered 15/1, 2020 at 9:54 Comment(1)
Welcome to SO! Please do not post screenshots of error messages. Take the time it requires you to provide the message as searchable text. You might want to have a look at this discussion if interested in reasoning.High

© 2022 - 2024 — McMap. All rights reserved.