【问题标题】:In Netty 4, how do I catch all handlers' unprocessed exceptionCaught?在 Netty 4 中,如何捕获所有处理程序的未处理异常捕获?
【发布时间】:2014-01-16 02:34:48
【问题描述】:

在我的通道管道中,有很多处理程序。

据我了解,如果我不覆盖他们的 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,所以我认为不使用反射我不能轻易地覆盖它。有没有更好的办法?

【问题讨论】:

    标签: netty


    【解决方案1】:

    您可以通过定义 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 方法中编码您的特定逻辑。但永远不要重新抛出异常,因为这是管道的结束。

    【讨论】:

      【解决方案2】:

      不知道为什么你的 exceptionCaught 方法会抛出异常......我想你只是想重写 ChannelHandler.exceptionCaught(..) 方法并在那里处理它。

      【讨论】:

      • 我可以在覆盖所有入站处理程序的exceptionCaught 时捕获异常。但是因为我正在编写 Web 框架,所以框架用户可以将用户创建的处理程序(不进行覆盖)传递给框架,即使处理程序没有覆盖 exceptionCaught,我也想捕获所有异常。
      • 只要确保你总是在 ChannelPipeline 中有最后一个 ChannelInboundHandler 覆盖 exceptionCaught(...)
      猜你喜欢
      • 1970-01-01
      • 2011-02-16
      • 1970-01-01
      • 2012-09-16
      • 2010-09-21
      • 1970-01-01
      • 2014-09-02
      • 2017-11-25
      • 2018-06-14
      相关资源
      最近更新 更多