Подтвердить что ты не робот

Как поймать все исключения в нетти

Насколько я знаю исключения обработки Netty методом override exceptionCaught(). Но я хочу обработчик, который может обрабатывать все исключения в или из. Итак, трубопровод должен выглядеть следующим образом:

InboundExceptionHandler - inboundHandler1 - inboundHandler2 - outboundHandler1 - outboundHandler2 - OutboundExceptionHandler

Это означает, что я должен разместить 2 обработчика исключений в моем конвейере, разделенных в голове и хвосте. Но я думаю, что это выглядит уродливо. любая лучшая идея?

4b9b3361

Ответ 1

У вас может быть только один обработчик исходящих и исходящих исключений в верхней части/хвосте вашего конвейера. Если вы хотите поймать все исключения, вы можете сделать что-то вроде этого (я предполагаю, что это 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...
                }
            }
        }));
    }

    @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...
                }
            }
        }));
    }

    // ... override more outbound methods to handle their exceptions as well
}

Любые исключения, которые генерируются входящими обработчиками, будут распространять "вверх" на конвейер и вызывать этот метод обработчика exceptionCaught(), предполагая, что обработчик ниже не потребляет их.

Для исходящих операций, таких как write() и connect(), вам нужно добавить ChannelFutureListener, чтобы уловить их исключения. Метод exceptionCaught() вызывается только для исключений из входящих событий, таких как channelRead(), channelActive() и т.д.

С помощью этого обработчика на "вершине" конвейера мы можем поймать исключения из всех обработчиков исходящих сообщений ниже. Скажем, что один из ваших обработчиков исходящих пакетов выполняет некоторую кодировку, и это не удается с исключением, это будет обработано нашим будущим слушателем канала, добавленным к обещанию операции write().

Если этот обработчик исключений был установлен на "нижнем" /главном конвейере, как вы изначально предложили, тогда он не увидит исключений из обработчиков над ним, потому что его метод write() никогда не будет вызываться, если сбой записи в предыдущий обработчик. Вот почему этот обработчик должен быть наверху.

Чтобы надеяться избежать путаницы в верхней/нижней части конвейера, вот как я буду настраивать конвейер вашего примера:

pipeline.addLast(outboundHandler2)        // bottom
        .addLast(outboundHandler1)
        .addLast(inboundHandler2)
        .addLast(inboundHandler1)
        .addLast(new ExceptionHandler()); // top