Перейти к основному содержимому

Исключения в Нетти

· 3 мин. чтения

1. Обзор

В этой быстрой статье мы рассмотрим обработку исключений в Netty.

Проще говоря, Netty — это платформа для создания высокопроизводительных асинхронных и управляемых событиями сетевых приложений. Операции ввода-вывода обрабатываются внутри его жизненного цикла с использованием методов обратного вызова.

Подробнее о фреймворке и о том, как с ним начать работу, можно прочитать в нашей предыдущей статье здесь .

2. Обработка исключений в Netty

Как упоминалось ранее, Netty является системой, управляемой событиями, и имеет методы обратного вызова для определенных событий. Исключениями являются и такие события.

Исключения могут возникать при обработке данных, полученных от клиента, или во время операций ввода-вывода. Когда это происходит, запускается специальное событие исключения.

2.1. Обработка исключений в канале происхождения

Событие, перехваченное исключением, при запуске обрабатывается методом exceptionsCaught () объекта ChannelInboundHandler или его адаптеров и подклассов.

Обратите внимание, что обратный вызов устарел в интерфейсе ChannelHandler . Теперь он ограничен интерфейсом ChannelInboudHandler .

Метод принимает объект Throwable и объект ChannelHandlerContext в качестве параметров. Объект Throwable можно использовать для печати трассировки стека или получения локализованного сообщения об ошибке.

Итак, давайте создадим обработчик канала ChannelHandlerA и переопределим его exceptionCaught() с помощью нашей реализации:

public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) 
throws Exception {

logger.info(cause.getLocalizedMessage());
//do more exception handling
ctx.close();
}

В приведенном выше фрагменте кода мы зарегистрировали сообщение об исключении, а также вызвали метод close() для ChannelHandlerContext .

Это закроет канал между сервером и клиентом. По сути, заставляя клиента отключиться и завершить работу.

2.2. Распространение исключений

В предыдущем разделе мы обработали исключение в его исходном канале. Однако на самом деле мы можем передать исключение другому обработчику канала в конвейере.

Вместо регистрации сообщения об ошибке и вызова ctx.close() мы будем использовать объект ChannelHandlerContext для запуска другого события, перехваченного исключением, вручную .

Это приведет к вызову exceptionCaught() следующего обработчика канала в конвейере.

Давайте изменим фрагмент кода в ChannelHandlerA для распространения события, вызвав ctx.fireExceptionCaught() :

public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) 
throws Exception {

logger.info("Exception Occurred in ChannelHandler A");
ctx.fireExceptionCaught(cause);
}

Кроме того, давайте создадим еще один обработчик канала, ChannelHandlerB , и переопределим его exceptionCaught() с помощью этой реализации:

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {

logger.info("Exception Handled in ChannelHandler B");
logger.info(cause.getLocalizedMessage());
//do more exception handling
ctx.close();
}

В классе Server каналы добавляются в конвейер в следующем порядке:

ch.pipeline().addLast(new ChannelHandlerA(), new ChannelHandlerB());

Распространение событий, перехваченных исключениями, вручную полезно в тех случаях, когда все исключения обрабатываются одним назначенным обработчиком канала.

3. Заключение

В этом руководстве мы рассмотрели, как обрабатывать исключения в Netty с помощью метода обратного вызова и как при необходимости распространять исключения.

Полный исходный код доступен на Github .