2015-11-19 2 views
8

私はFutureを返す関数を見つけましたが、すぐに例外をスローします。たとえば、次のように:あなたは両方のエラーをキャッチするために、このような何かをしなければならないのでFuture [A]を返す関数は例外をスローする必要がありますか?

def func(): Future[String] { 
    if (something) { 
    // this 
    Future.failed(new RuntimeException("test")) 
    } else { 
    // and this 
    throw new RuntimeException("test") 
    } 
} 

この動作は、呼び出し元に対する迷惑なようだ:

try { 
    func() recover { 
    case e: Exception => handleError(e) 
    } 
} catch { 
    case e: Exception => Future.successful(handleError(e)) //or Future.failed etc 
} 

私がプレイ枠組みの中でWSClientがないことに気づきましたこれは、URLが不正な場合は例外をスローし、HTTP要求が失敗した場合は失敗するFutureを返します。

これは良い方法ですか?このように動作する関数からエラーを処理するには、より良い方法がありますか?

+0

いいえ、例外を使用することはおすすめできません - http://programmers.stackexchange.com/questions/223329/side-effects-side-effects-breaking-referential-transparencyおそらく 'Future [A、B]]を使ってhttps://www.reddit.com/r/scala/comments/3r5ii6/on_handling_futureeithera_b_sequencing/に合っているでしょう。 –

+0

@KevinMeredith私は[A、B]のいずれかを使用してエラーを予測していますが、ここでの問題はそれらを区別する方法ではなく、例外をスローして予期せぬ失敗に対して失敗した先物を返す必要があるかどうかです。 )。 –

答えて

4

Future最終的に何かを返すために使用されますが、これが実際に発生したときには明確ではありません。

.NETの観点から(私たちはTaskです)、要求が間違っている(不正な形式のURLなど)場合は、例外をスローする必要があります。実際にWebリクエストを行う前にこれを知っているので、例外を遅らせる必要はありません。

一方、サーバーがダウン(タイムアウト?)している場合、またはサーバーがクライアントに理解できないものを返す場合、これは後で処理する必要があります。応答を直接作成できないため呼び出し。応答が利用できるようになるまでブロックすることができますが、それはFutureを役に立たなくします。

これは、「早期終了」プログラミングスタイルと比較すると最もよいと思います。

+4

これは実際にはScalaでは慣用的ではありません。回復可能なエラーはいつ発生しても、スローされずに将来失敗するはずです。 –

+0

私はそれが完璧な答えになると思います。 :) – Caramiriel

関連する問題