Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to catch all exception in netty

As far as I know netty handle exceptions by override method exceptionCaught(). But what I want is a Handler that can handler all exceptions in or out. So, the pipeline should be like :

InboundExceptionHandler - inboundHandler1 - inboundHandler2 - outboundHandler1 - outboundHandler2 - OutboundExceptionHandler

That means I should place 2 exception Handler in my pipeline separated in head and tail. But I think it looks ugly. any better idea?

like image 748
Alexis Avatar asked Jun 23 '15 04:06

Alexis


People also ask

How do you catch all exceptions?

Exception handling is used to handle the exceptions. We can use try catch block to protect the code. Catch block is used to catch all types of exception. The keyword “catch” is used to catch exceptions.

How do you catch exceptions without trying?

throws: The throws keyword is used for exception handling without try & catch block. It specifies the exceptions that a method can throw to the caller and does not handle itself.


1 Answers

You could just have a single inbound and outbound exception handler at the top/tail of your pipeline. If you want to catch all exceptions you could do something like this (I'm assuming this is 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
}

Any exceptions that are thrown by inbound handlers will propagate "up" the pipeline and invoke this handler's exceptionCaught() method, assuming a handler below does not consume them.

For outbound operations like write() and connect(), you need to add a ChannelFutureListener to catch their exceptions. The exceptionCaught() method is only invoked for exceptions from inbound events like channelRead(), channelActive() etc.

With this handler at the "top" of the pipeline we can catch exceptions from all outbound handlers below. Say one of your outbound handlers is doing some encoding and this fails with an exception, this will be handled by our channel future listener that we added to the write() operation's promise.

If this exception handler was installed at the "bottom"/head of the pipeline like you initially suggested, then it would not see exceptions from handlers above it, because its write() method would never be invoked if the write failed in a previous handler. That's why this handler must be at the top.

To hopefully avoid confusion about top/bottom of the pipeline, here is how I would configure your example pipeline:

pipeline.addLast(outboundHandler2)        // bottom
        .addLast(outboundHandler1)
        .addLast(inboundHandler2)
        .addLast(inboundHandler1)
        .addLast(new ExceptionHandler()); // top
like image 69
Ben Evans Avatar answered Oct 05 '22 16:10

Ben Evans