【发布时间】:2018-11-09 18:21:03
【问题描述】:
在 Netty 中,您有入站和出站处理程序的概念。一个包罗万象的入站异常处理程序只需在管道的末端(尾部)添加一个通道处理程序并实现exceptionCaught 覆盖即可实现。沿入站管道发生的异常将沿处理程序传播,直到遇到最后一个,如果沿途未处理。
传出处理程序并没有完全相反的情况。相反(根据 Netty in Action,第 94 页),您需要将侦听器添加到 channel 的 Future 或将侦听器添加到 Promise 传递到您的 write 方法的 @987654326 @。
由于我不确定在哪里插入前者,我想我会选择后者,所以我做了以下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
问题是如果我在HttpLoggerHandler.write() 中抛出运行时异常,我的错误处理程序的write 方法永远不会被调用。
我将如何进行这项工作?任何传出处理程序中的错误都应该“冒泡”到附加到头部的错误。
需要注意的重要一点是,我不仅想关闭频道,我还想将错误消息写回客户端(从serverErrorJSON('...') 可以看出。在我尝试改组的过程中处理程序(也尝试来自this answer的东西),我已经激活了监听器,但我无法写任何东西。如果我在监听器中使用ctx.write(),看起来好像我进入了一个循环,同时使用@ 987654334@ 什么都没做。
【问题讨论】:
标签: asynchronous exception exception-handling netty