2016-12-19 18 views
1

RuntimeExceptionsはプログラミングエラーを示すはずで、私の観測所の中に何かRuntimeExceptionがスローされたときにアプリケーションがクラッシュするようにします。RuntimeExceptionベストプラクティスを処理する

これを行うにはどのような方法が最適ですか?今私は、このソリューションを(それはKotlinだが、私はそれが理解できる願っています)

fun <T> Observable<T>.subscribeCrashOnRuntimeException(onNext: (T) -> Unit, onError: (Throwable) -> Unit) { 
    this.subscribe({ 
    onNext(it) 
    }, { e -> 
    if (e is RuntimeException) { 
     throw e 
    } else { 
     onError(e) 
    } 
    }) 
} 

fun usageExample() { 
    val observable = Observable.just(1) 
    observable.subscribeCrashOnRuntimeExceptions(
    { next -> Log.d("TAG", "next: $next") }, 
    { e -> Log.d("TAG", "error: $e") } 
) 
} 

しかし、私はそれに疑問を持って検討しています。たとえば、このソリューションで特定のRuntimeExceptionsを時折「キャッチ」することは難しいです。おそらく、私はちょうどGoogleの方法を知らない状況に対処するためのよく知られた方法がありますか?

+0

読むあなたがエラーで何をすべきかを決めることができます 'onErrorResumeNext'について。 – akarnokd

+0

'RuntimeExceptionsはプログラミングエラーを示すはずです - 必ずしもそうではありません。不足しているファイルにプログラミングエラーがありますか?ネットワーク接続が切断されていますか?あなたが明示的にクラッシュすることはしませんが、緩和または再試行することがほとんどです。 –

+0

@TassosBassoukosファイルが見つからないのはRuntimeExceptionsではありません。ネットワーク接続が切断された場合でも同じです。あなたがRuntimeExceptionsを理解できないようです。あなたがExceptionの同義語だと思うようです。 –

答えて

1

ランタイム(別名未チェック)または通常(別名チェック済み)例外の処理に大きな違いがあるはずはないと思います。どちらも現在広く使用されており、特定の状況に応じて回復可能かどうかが問われます。エラー処理の

反応性の方法があります。onErrorResumeNextまたはonErrorReturn事業者を経由して

  1. 。これらはエラーを検査し、おそらくそれから回復することを可能にする。
  2. 経由でretry*オペレータファミリー。これらは、エラーを検査し、再購読(例えば、ネットワークコールの再試行)によって回復される可能性があります。
  3. onErrorあなたの加入者のコールバック。 How to handle different kinds of errors in Retrofit Rx onError without ugly instanceof

    また欠点を注意してください。あなたのプログラムクラッシュ

関連トピックますので、あなたは、エラーが通常のJavaの方法で再スローされます、このようなコールバックを指定しない場合の方法により、通常のJavaの方法で例外をスローする:

    メッセージ処理中の呼び出しスタックは、メッセージ処理ルールを定義するときの呼び出しスタックとは異なります。これは、スタックトレースを解釈するだけでなく、そのような例外をキャッチすることはかなり難しい可能性があることを意味します。
  • スケジューラによってキャッチされた例外は、つまり、あなたのプログラムが壊れた状態でぶら下がって終わるかもしれない

サンプルコード

Observable.fromCallable(() -> { 
    ... 
    if (ok) return "Success!"; 
    else throw new RuntimeException("Failure at source"); 
}) 
.map(s -> { 
    ... processing is bypassed in case of an error 
}) 
.map(s -> { 
    ... 
    if (...) return s.upperCase(); 
    else throw new RuntimeException("Failure during processing"); 
}) 
.onErrorReturn(e -> { 
    if (e.getMessage().contains("processing")) 
     return "Recovered"; 
    throw Exceptions.propagate(e); // let it continue as an error 
}) 
.subscribe(s -> println("got result: " + s), 
      e -> println("got error: " + e); 

すべての例外はRxJavaによってキャッチされ、定義されたルートに沿って渡されます。

onError*オペレータは中間のcatchブロックのように動作します。

サブスクライバのonErrorコールバックは、トップレベルcatchブロックのように動作します。件名に

その他のリンク:

+0

データまたはエラーのいずれかを返さなければならない観測可能性があるとします。たとえば、http要求を実行するobservableです。これらのリターンタイプは両方とも有効であり、加入者は両方のリターンタイプに対応できる必要があります。だから、私はこの状況を処理する "公式" RxJavaの方法は、 "どちらかのデータやエラー"オブジェクトを返すことを理解している。 onError()コールバックを提供しないでください。そのため、予期しないエラーが発生した場合にアプリケーションがクラッシュします。私は正しい?このアプローチが大部分の定型文をもたらすように感じますが、多分私は間違っていると思います。 –

+0

@DmitryRyadnenko HTTPリクエストを実行するObservableは、* response *または* throw * exceptionのいずれかを返す必要があります。これは、RxJavaによって捕捉され、エラーとして行の下にルーティングされ、サブスクライバの 'onError'コールバックで終了します。 –

+0

これは私が今やっていることです、そして、私は各onErrorメソッドで同じ定型文で終わりました。 Like https://gist.github.com/rongi/3955d4946231c195d04adf110928a2ed これは私のそうでなければシンプルできれいな購読コードを汚染しているので、質問に記載されている解決方法があります。これは私の加入者コードを再びきれいにしました。 同じ問題がありましたか?あなたはこれを問題として見ていますか?これにどのように対処していますか? –

関連する問題