在Netty 4中,如何捕获所有处理程序的未处理异常捕获?

时间:2014-01-16 02:34:49

标签: netty

在我的频道管道中,有许多处理程序。

据我了解,如果我不覆盖他们的exceptionCaught(ChannelHandlerContext ctx, Throwable cause)方法,默认行为是cause将被抛出到管道,这样的东西将被记录在WARN级别管道:

An exception was thrown by a user handler's exceptionCaught() method while handling the following exception: ...

我想覆盖上面的管道行为以添加一些特定的逻辑(例如:如果causejava.io.IOException: Connection reset by peer,请不要记录任何内容以避免在WARN级别上有太多“不太有用”的日志)。

我该怎么办?

经过一番调查,我发现了这个源代码: https://github.com/netty/netty/blob/4.0/transport/src/main/java/io/netty/channel/DefaultChannelHandlerContext.java

private void invokeExceptionCaught(final Throwable cause) {
    try {
        handler.exceptionCaught(this, cause);
    } catch (Throwable t) {
        if (logger.isWarnEnabled()) {
            logger.warn(
                    "An exception was thrown by a user handler's " +
                    "exceptionCaught() method while handling the following exception:", cause);
        }
    }
}

因为它是private,我认为如果不使用反射我就不能轻易地覆盖它。还有更好的方法吗?

2 个答案:

答案 0 :(得分:5)

您可以通过定义ExceptionHandler然后将此处理程序放在管道的尾部来完成此操作。

ChannelPipeline p = ch.pipeline();
p.addLast("business", new SomeBusinessHandler());
p.addLast...
p.addLast("exception", new ExceptionHandler());//Make sure this is the last line when init the pipeline.

并在exceptionCaught方法中编码您的特定逻辑。但永远不要重新抛出异常,因为这是管道的终结。

答案 1 :(得分:3)

不确定为什么你的exceptionCaught方法会抛出异常......我想你只想覆盖ChannelHandler.exceptionCaught(..)方法并在那里处理它。