Java 如何在netty中捕获所有异常

Java 如何在netty中捕获所有异常,java,exception-handling,netty,Java,Exception Handling,Netty,据我所知,netty通过重写方法exceptionCaught()来处理异常。但我想要的是一个可以处理所有异常的处理程序。因此,管道应该是这样的: InboundExceptionHandler-inboundHandler1-inboundHandler2-outboundHandler1-outboundHandler2-OutboundExceptionHandler 这意味着我应该在我的管道中放置两个异常处理程序,它们在头部和尾部是分开的。但我觉得它看起来很丑。有更好的主意吗?您可以在管

据我所知,netty通过重写方法exceptionCaught()来处理异常。但我想要的是一个可以处理所有异常的处理程序。因此,管道应该是这样的:

InboundExceptionHandler-inboundHandler1-inboundHandler2-outboundHandler1-outboundHandler2-OutboundExceptionHandler


这意味着我应该在我的管道中放置两个异常处理程序,它们在头部和尾部是分开的。但我觉得它看起来很丑。有更好的主意吗?

您可以在管道的顶部/尾部设置一个入站和出站异常处理程序。如果您想捕获所有异常,可以这样做(我假设这是Netty 4.0):

入站处理程序引发的任何异常都将“向上”传播管道并调用此处理程序的
exceptionCaught()
方法,前提是下面的处理程序不使用它们

对于诸如
write()
connect()
之类的出站操作,您需要添加一个
ChannelFutureListener
来捕获它们的异常仅当来自入站事件(如
channelRead()
channelActive()
等)的异常时调用
exceptionCaught()
方法。

使用管道“顶部”的这个处理程序,我们可以捕获下面所有出站处理程序的异常。假设您的一个出站处理程序正在执行某些编码,但由于出现异常而失败,这将由我们添加到
write()
操作承诺中的通道未来侦听器处理

如果此异常处理程序像您最初建议的那样安装在管道的“底部”/“头部”,那么它将不会看到来自其上方处理程序的异常,因为如果在以前的处理程序中写入失败,它的
write()
方法将永远不会被调用。这就是为什么这个处理器必须在顶部

为了避免对管道顶部/底部的混淆,下面是我将如何配置示例管道:

pipeline.addLast(outboundHandler2)        // bottom
        .addLast(outboundHandler1)
        .addLast(inboundHandler2)
        .addLast(inboundHandler1)
        .addLast(new ExceptionHandler()); // top

这不能与写入时的voidPromise一起使用,也不能以最小化不必要的对象创建的方式使用。您能详细介绍一下优化的版本吗?如果您使用voidPromise进行写操作,那么您不能调用addListener(),但是任何出站写异常都会传播到exceptionCaught(),因此它们仍然可以在那里处理。在4.1中,您可以调用promise.isVoid()来处理这两种情况。为了尽量减少对象创建,我上面使用的ChannelFutureListener匿名类可以声明为实例成员,这样每个处理程序只创建一次。我理解入站部分,但对出站部分感到困惑。假设有一条传入消息通过管道传输
inboundHandler1
接收消息,然后通过调用
ctx.write()
进行响应。由于
ExceptionHandler
从不涉及此消息,如何调用其
write()
方法来设置promise回调?我想我一定是遗漏了什么…你是对的,如果在处理入站消息时从另一个处理程序调用了
ctx.write()
,则
ExceptionHandler
将不知道它。您有几个选项:-创建一个ChannelPromise(
ctx.newPromise()
)并向其中添加您自己的侦听器,以处理当前ChannelHandler中的异常-使用
ctx.write(message,ctx.voidPromise())
-如果使用无效承诺是安全的,那么任何写入异常都将传播到
ExceptionHandler
exceptionCaught
方法。相关问题:
pipeline.addLast(outboundHandler2)        // bottom
        .addLast(outboundHandler1)
        .addLast(inboundHandler2)
        .addLast(inboundHandler1)
        .addLast(new ExceptionHandler()); // top