2016-07-13 19 views
0

以下のコードでは、tryブロック内の最初の行でConnectExceptionがスローされたときに捕捉されません。元の例外メッセージ "Connection Refused"はデバッグには役に立たないので、私は例外を取り返しているので、いくつかの情報を追加しています。しかし、「接続に失敗しました...」というメッセージが表示されることはありません。私は元の "Connection Refused"例外メッセージしか見ない。ScalaのScalaのTry/Catchブロックが例外をキャッチできません

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")) 
    } 
    } 

私が手出力は次のようになります。

私は| 16:25:15.561 | ogsmessaging.MessageBusManagerの$ | NATS java.net.ConnectExceptionを開始:接続がsun.nioで を拒否しました。 ch.Net.connect0(ネイティブメソッド) at sun.nio.ch.Net.connect(Net.java:454) at sun.nio.ch.Net.connect(Net.java:446) at sun.nio .ch.SocketChannelImpl.connect(SocketChannelImpl.java:648) java.nio.channels.SocketChannel.open(SocketChannel.java:189)。。org.nats.Connection.connect(Connection.java:211)org.nats.Connectionで (Connection.java:164) org.nats.Conn ATで(Conn.scala:5)ORGで 。 nats.Conn $ .connect(Conn.scala:68) at org.genivi.sota.messaging.nats.NatsClient $$ anonfun $ getClient $ 1 $$ anonfun $ apply $ 3 $$ anonfun $ apply $ 4 $$ anonfun $ apply $ 5 $$ anonfun $ apply $ 6.apply(NatsClient.scala:30)

例外メッセージは、catchブロックのものと一致しないことに注意してください。 NatsClient:30はcatchブロックの最初の行です

上記のコードは、scala_natsを使用してNATSメッセージングサーバーに接続しようとしています。キャッチケースをThrowableに変更しても、例外はまだ捕捉されません。しかし、tryの最初の行にConnectExceptionをスローすると、その例外が捕捉されます。また、ルートをインポートに追加して、名前空間の競合がないことを確認しました。無駄です。

ここで例外をキャッチできないのはどのような状況ですか?

+2

どのようにキャッチされていないと判断しますか? – Dima

+0

元のConnectExceptionには「Connection Refused」というメッセージがあります。スローされた例外には別の文字列がありますが、ログに「Connection Refused」としか表示されません。 – CalumMcCall

+0

おそらく、それをキャッチする前にログに記録されていますか? – Dima

答えて

2

Java_Natsライブラリ内のConnection.javaの関連するコードスニペット:

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; 
} 

あなたのスタックトレースによると、SocketChannel.open()は失敗します。例外がキャッチされ、記録され、飲み込まれるので、ハンドラには届きません。

N.b.上記のコードはライブラリのバージョン0.5.1からのものです。最新(0.6.0)のものが更新され、IOExceptionがスローされ、ログはスローされません。


は(私のオリジナルの答えは、例外がキャッチされていますが、すぐに別のものを投げる完全にオフ:)

ました。私は の代わりにXor.left として例外オブジェクトを返す(スローしない)と考えています。 (少なくとも、これは宣言された返品タイプ ConfigException Xor Connが示唆しているものです。)

+0

私ははっきりしていませんでした。私はデバッグを助けるために追加された情報を加えて例外を取り返しています。問題は、catchブロックが決して実行されないことです。 – CalumMcCall

+0

私は本当に0.5.1を使用しています。偉大な答えをありがとう、特に私の不明な質問がある。 – CalumMcCall

2

ConnectExceptionは、この行に巻き込まれている:

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

しかし、あなたはすぐに別のConnectExceptionを投げています。

一般的に言えば、別の例外で例外をラップするべきではありません。

ここからわかるように、tryブロックを使用しないでください!

+0

はい、この場合、例外を再発行する前に、例外にさらに情報を追加しています。しかし、例外は決して再スローされません。 – CalumMcCall

+0

正確には、おそらくより良い情報を持つ* new *例外インスタンスを作成しています。あなたは捕まえられたものを投げ捨てることはありません。 – Det

+0

はい、そうです。申し訳ありませんが、私はそこに明確ではなかった。 – CalumMcCall

関連する問題