I am looking for ways to handle exceptions in the inbound and outbound handlers and came up short on the latter (even after consulting p94 of Netty in Action). I am double posting this here, after not seeing much action on
StackOverflow.
A catch-all inbound exception handler is implemented simply by adding a channel handler at the end (the tail) of the pipeline and implementing an `exceptionCaught` override. The exception happening along the inbound pipeline will travel along the handlers until meeting the last one, if not handled along the way. This works fine.
There isn't an exact opposite for outgoing handlers. Instead (according to Netty in Action, page 94) you need to either add a listener to the _channel's_ `Future` or a listener to the `Promise` passed into the `write` method of your `Handler`.
As I am not sure where to insert the former in our code, I thought I'd go for the latter, so I made the following `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);
}
};
This is then added to the head of the pipeline:
@Override
public void addHandlersToPipeline(final ChannelPipeline pipeline) {
pipeline.addLast(
createOutgoingErrorHandler(),
new HttpLoggerHandler(), // an error in this `write` should go "up"
authHandlerFactory.get(),
myApplicationLogicHandler1,
myApplicationLogicHandler2,
// etc
The problem is that the `write` method of my error handler is never called if I throw a runtime exception in the `HttpLoggerHandler.write()`. It isn't sent up the pipeline, like with inbound handlers (where it is passed down).
How would I make this work? An error in any of the outgoing handlers should "bubble up" to the one attached to the head, AFAIK.
An important thing to note is that I don't merely want to close the channel, I want to write an error message back to the client (as seen from `serverErrorJSON('...')`. During my trials of shuffling around the order of the handlers (also trying out stuff from [this answer][1]), I have gotten the listener activated, but I was unable to write anything. If I used `ctx.write()` in the listener, it seems as if I got into a loop, while using `future.channel().write...` didn't do anything.
[1]:
https://stackoverflow.com/q/30994095/200987