如何捕获 netty 中的所有异常
2022-09-04 00:56:33
据我所知,netty通过覆盖方法 exceptionCaught()来处理异常。但是我想要的是一个可以处理所有异常的处理程序。所以,管道应该像这样:
入站异常处理程序 - 入站处理程序1 - 入站处理程序2 - 出站处理程序1 - 出站处理程序2 - 出站异常处理程序
这意味着我应该在我的管道中放置2个异常处理程序,以头部和尾部分隔。但我认为它看起来很丑陋。任何更好的主意?
据我所知,netty通过覆盖方法 exceptionCaught()来处理异常。但是我想要的是一个可以处理所有异常的处理程序。所以,管道应该像这样:
入站异常处理程序 - 入站处理程序1 - 入站处理程序2 - 出站处理程序1 - 出站处理程序2 - 出站异常处理程序
这意味着我应该在我的管道中放置2个异常处理程序,以头部和尾部分隔。但我认为它看起来很丑陋。任何更好的主意?
您可以在管道的顶部/尾部有一个入站和出站异常处理程序。如果你想抓住所有的异常,你可以做这样的事情(我假设这是Netty 4.0):
import io.netty.channel.*;
import java.net.SocketAddress;
public class ExceptionHandler extends ChannelDuplexHandler {
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
// Uncaught exceptions from inbound handlers will propagate up to this handler
}
@Override
public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
ctx.connect(remoteAddress, localAddress, promise.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
if (!future.isSuccess()) {
// Handle connect exception here...
Throwable failureCause = future.cause();
}
}
}));
}
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
ctx.write(msg, promise.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
if (!future.isSuccess()) {
// Handle write exception here...
Throwable failureCause = future.cause();
}
}
}));
}
// ... override more outbound methods to handle their exceptions as well
}
入站处理程序引发的任何异常都将“向上”传播管道并调用此处理程序的方法,前提是下面的处理程序不使用它们。exceptionCaught()
对于像 和 这样的出站操作,您需要添加 一个来捕获它们的异常。exceptionCaught()
方法仅针对来自入站事件(如 channelRead()、channelActive()
等)
的异常调用。write()
connect()
ChannelFutureListener
使用此处理程序位于管道的“顶部”,我们可以从下面的所有出站处理程序中捕获异常。假设您的一个出站处理程序正在执行一些编码,并且这失败并出现异常,这将由我们添加到操作承诺中的通道未来侦听器处理。write()
如果此异常处理程序像您最初建议的那样安装在管道的“底部”/头部,则不会看到来自其上方处理程序的异常,因为如果在以前的处理程序中写入失败,则永远不会调用其方法。这就是为什么这个处理程序必须位于顶部。write()
为了避免对管道的顶部/底部感到困惑,以下是我如何配置您的示例管道:
pipeline.addLast(outboundHandler2) // bottom
.addLast(outboundHandler1)
.addLast(inboundHandler2)
.addLast(inboundHandler1)
.addLast(new ExceptionHandler()); // top
最终的解决方案是自定义通道初始化器您甚至可以添加更多逻辑