捕获出站ChannelHandler的所有异常处理

问题描述 投票:3回答:2

在Netty中,您有入站和出站处理程序的概念。只需在管道的末尾(尾部)添加通道处理程序并实现exceptionCaught覆盖,即可实现catch-all入站异常处理程序。沿着入站管道发生的异常将沿着处理程序传递,直到遇到最后一个,如果不是沿途处理的话。

传出处理程序没有完全相反的情况。相反(根据Netty in Action,第94页)你需要为通道的Future添加一个监听器,或者将Promise的监听器添加到你的writeHandler方法中。

因为我不知道在哪里插入前者,我以为我会选择后者,所以我做了以下ChannelOutboundHandler

}

/**
 * Catch and log errors happening in the outgoing direction
 *
 * @see <p>p94 in "Netty In Action"</p>
 */
private ChannelOutboundHandlerAdapter createOutgoingErrorHandler() {
    return new ChannelOutboundHandlerAdapter() {
        @Override
        public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
            logger.info("howdy! (never gets this far)");

            final ChannelFutureListener channelFutureListener = future -> {
                if (!future.isSuccess()) {
                    future.cause().printStackTrace();
                    // ctx.writeAndFlush(serverErrorJSON("an error!"));
                    future.channel().writeAndFlush(serverErrorJSON("an error!"));
                    future.channel().close();
                }
            };
            promise.addListener(channelFutureListener);
            ctx.write(msg, promise);
        }
    };

这被添加到管道的头部:

@Override
public void addHandlersToPipeline(final ChannelPipeline pipeline) {
    pipeline.addLast(
            createOutgoingErrorHandler(),
            new HttpLoggerHandler(), // an error in this `write` should go "up"
            authHandlerFactory.get(),
            // etc

问题是,如果我在write中抛出运行时异常,我的错误处理程序的HttpLoggerHandler.write()方法永远不会被调用。

我怎么做这个工作?任何传出处理程序中的错误都应该“冒泡”到连接到头部的错误。

需要注意的一点是,我不仅要关闭通道,还要将错误信息写回客户端(如serverErrorJSON('...')所示。在我对处理程序的顺序进行改组试验期间(也尝试了)来自this answer的东西),我已经启动了监听器,但我无法写任何东西。如果我在监听器中使用ctx.write(),似乎我进入了一个循环,而使用future.channel().write...没有做任何事情。

asynchronous exception exception-handling netty
2个回答
© www.soinside.com 2019 - 2024. All rights reserved.