2016-07-13 6 views
0

Wenn im folgenden Code eine ConnectException von der ersten Zeile innerhalb des try-Blocks ausgelöst wird, wird sie nicht abgefangen. Ich wiederhole die Ausnahme, da die ursprüngliche Ausnahmebedingungsnachricht "Connection Refused" zum Debuggen nicht hilfreich ist. Daher füge ich weitere Informationen hinzu. Meine Ausnahme mit der Meldung "Verbindung fehlgeschlagen ..." wird jedoch nie angezeigt. Ich sehe immer nur die ursprüngliche "Connection Refused" Exception-Nachricht.Scala Try/Catch-Block in Scala schlägt fehl Exception

private[this] def getClient(system: ActorSystem, config: Config): ConfigException Xor Conn = 
    for { 
    natsConfig <- config.configAt("messaging.nats") 
    userName <- natsConfig.readString("user") 
    password <- natsConfig.readString("password") 
    host  <- natsConfig.readString("host") 
    port  <- natsConfig.readString("port") 
    } yield { 
    val props = new Properties() 
    props.put("servers", "nats://" + userName + ":" + password + "@" + host + ":" + port) 
    log.debug("NATS connection properties:" + props.getProperty("servers")) 
    try { 
     val client = Conn.connect(props) 
     system.registerOnTermination { 
     client.close() 
     } 
     client 
    } catch { 
     case ex:ConnectException => 
     throw new ConnectException("Failed to connect to nats using props:" + props.getProperty("servers")) 
    } 
    } 

Der Ausgang ich erhalte, ist:

I | 16: 25: 15,561 | ogsmessaging.MessageBusManager $ | Start NATS java.net.ConnectException: Anschluss bei sun.nio abgelehnt. ch.Net.connect0 (Native Methode) bei sun.nio.ch.Net.connect (Net.java:454) bei sun.nio.ch.Net.connect (Net.java:446) bei sun.nio .ch.SocketChannelImpl.connect (SocketChannelImpl.java:648) unter java.nio.channels.SocketChannel.open (SocketChannel.java:189) bei org.nats.Connection.connect (Connection.java:211) bei org.nats.Connection. (Connection.java:164) bei org.nats.Conn. (Conn.scala: 5) bei org. nat.Conn $ .connect (Conn.scala: 68) bei org.genivi.sota.messaging.nats.NatsClient $$ anonfun $ getClient $ 1 $$ anonfun $ anwenden $ 3 $$ anonfun $ anwenden $ 4 $$ anonfun $ anwenden $ 5 $$ anonfun gelten $ $ 6.Apply (NatsClient.scala: 30)

Beachten Sie die Ausnahmemeldung, die nicht mit der im catch-Block entspricht. NatsClient: 30 ist die erste Zeile des Catch-Blocks

Der obige Code versucht, eine Verbindung zu einem NATS-Messaging-Server mit scala_nats herzustellen. Selbst wenn ich den Catch-Fall in Throwable ändere, wird die Ausnahme immer noch nicht abgefangen. Wenn ich jedoch eine ConnectException in die erste Zeile des Befehls try, wird diese Ausnahme abgefangen. Ich habe auch versucht, root zu meinen Importen hinzuzufügen, um sicherzustellen, dass es keine Namensraumkonflikte gibt, ohne Erfolg.

Unter welchen Umständen kann Scala Ausnahmen hier nicht abfangen?

+2

Wie stellen Sie fest, dass es nicht gefangen wird? – Dima

+0

Die ursprüngliche ConnectException hat die Meldung "Verbindung abgelehnt". Die Ausnahme, die ich geworfen habe, hat eine andere Zeichenfolge, aber ich sehe nur "Verbindung abgelehnt" in den Protokollen. – CalumMcCall

+0

Vielleicht wird es protokolliert, bevor Sie es fangen? – Dima

Antwort

2

Der entsprechende Code-Schnipsel von Connection.java in der Java_Nats Bibliothek:

private boolean connect() throws IOException { 
    try { 
     InetSocketAddress addr = new InetSocketAddress(servers[current].host, servers[current].port); 
     channel = SocketChannel.open(addr); 
     while(!channel.isConnected()){}   
     servers[current].connected = true; 
    } catch(Exception ie) { 
     ie.printStackTrace(); 
     return false; 
    } 

    return true; 
} 

nach Ihrem Stack-Trace, nicht SocketChannel.open(). Dann wird die Ausnahme abgefangen, protokolliert und geschluckt, so dass sie Ihren Handler nicht erreicht.

N.b. Der obige Code stammt aus Version 0.5.1 der Bibliothek. Die neueste Version (0.6.0) wird aktualisiert und würde eine IOException, keine Protokollierung auslösen.


(Meine ursprüngliche Antwort war völlig weg :)

Die Ausnahme ist gefangen, aber sie sofort einen anderen werfen. Ich denke Sie beabsichtigen, das Ausnahmeobjekt als Xor.left stattdessen zurückzugeben (nicht zu werfen). (Zumindest ist dies der erklärte Rückgabetyp ConfigException Xor Conn schlägt vor. )

+0

Ich war nicht klar. Ich wiederhole die Ausnahme mit mehr Informationen, um das Debuggen zu erleichtern. Das Problem ist, dass der catch-Block nie ausgeführt wird. – CalumMcCall

+0

Ich verwende tatsächlich 0.5.1. Danke für die tolle Antwort, vor allem angesichts meiner unklaren Frage. – CalumMcCall

2

Die ConnectException auf dieser Linie wird gefangen:

} catch { 
    case ex:ConnectException => println("HELLO!!!") 

Aber Sie sofort ein anderes ConnectException werfen.

Im Allgemeinen sollten Sie eine Ausnahme nicht mit einer anderen Ausnahme umbrechen.

Von dem, was ich hier sehe, verwenden Sie keinen try Block überhaupt!

+0

Ja, aber in diesem Fall füge ich der Ausnahme weitere Informationen hinzu, bevor ich sie erneut austrage. Aber die Ausnahme wird nie wieder aufgegriffen. – CalumMcCall

+0

Um genau zu sein, erstellen Sie eine * neue * Ausnahme-Instanz mit vielleicht besseren Informationen, und Sie werfen das. Du wirfst den gefangenen nicht. – Det

+0

Ja, das ist richtig. Entschuldigung, ich war dort nicht klar. – CalumMcCall

Verwandte Themen