2015-06-23 26 views
8

O ile mi wiadomo, wyjątki obsługi NETty przez zastąpienie metody exceptionCaught(). Ale to, czego chcę, to Handler, który może obsłużyć wszystkie wyjątki. Tak, rurociąg powinien być jak:Jak wychwycić wszystkie wyjątki w netty

InboundExceptionHandler - inboundHandler1 - inboundHandler2 - outboundHandler1 - outboundHandler2 - OutboundExceptionHandler

Oznacza to, że należy umieścić 2 wyjątku Handler w moim rurociągu oddzielone w głowie i ogonie. Ale myślę, że wygląda brzydko. jakiś lepszy pomysł?

Odpowiedz

15

Może istnieć tylko jeden wyjątek obsługi przychodzącej i wychodzącej w górnej/dolnej części potoku. Jeśli chcesz złapać wszystkie wyjątki można zrobić coś takiego (jestem zakładając to 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 
} 

Wszelkie wyjątki, które są rzucane przez procedury obsługi przychodzących będzie propagować „w górę” rurociągu i wywołać tego przewodnika Metoda exceptionCaught(), zakładając, że program obsługi poniżej nie zużywa ich.

Dla operacji wychodzących, takich jak write() i connect(), należy dodać ChannelFutureListener, aby wychwycić wyjątki. Sposób exceptionCaught() jest wywoływany tylko wyjątki od zdarzeń przychodzących jak channelRead(), channelActive() itp

Z tego przewodnika na „top” rurociągu możemy złapać wyjątki ze wszystkich koparki wychodzących poniżej. Powiedzmy, że jedna z twoich funkcji obsługi wychodzącej wykonuje pewne kodowanie, co kończy się niepowodzeniem z wyjątkiem. Będzie to obsługiwane przez naszego przyszłego słuchacza naszego kanału, który dodaliśmy do obietnicy operacji write().

Jeśli ta procedura obsługi wyjątku została zainstalowana na "dole"/nagłówku potoku, tak jak początkowo sugerowałeś, to nie zobaczyłaby wyjątków od procedur obsługi nad nim, ponieważ jego metoda write() nigdy nie byłaby wywoływana, gdyby zapis nie poprzedni handler. Właśnie dlatego ten przewodnik musi być na górze.

Aby uniknąć nieporozumień z nadzieją o górnej/dolnej części rurociągu, oto jak bym skonfigurować przykładowy rurociągu:

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

thx ben! fajne rozwiązanie! – Alexis

+0

nie można tego używać z voidPromise przy zapisie lub w sposób minimalizujący niepotrzebne tworzenie obiektów. czy możesz rozwinąć więcej na zoptymalizowanej wersji –

+0

Jeśli używasz voidPromise do zapisu, nie możesz wywołać metody addListener(), ale wszelkie wyjątki zapisu wychodzącego będą propagować do exceptionCaught(), więc nadal mogą być tam obsługiwane. W wersji 4.1 możesz wywołać funkcję obietnicy.isVoid(), aby obsłużyć dowolny z tych przypadków. Aby zminimalizować tworzenie obiektów, klasy anonimowe ChannelFutureListener, których użyłem powyżej, mogłyby zostać zadeklarowane jako elementy instancji, więc są tworzone tylko raz dla każdego programu obsługi. –