2

RuntimeExceptions はプログラミング エラーを示すはずであり、observables 内の何かが 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 を時折「キャッチ」するのは困難です。おそらく、グーグルの方法がわからない状況に対処するためのよく知られた方法がありますか?

4

1 に答える 1

1

実行時 (チェックされていない) 例外と通常 (チェックされている) 例外の処理に大きな違いがあるとは思いません。どちらも最近では広く使用されており、特定の状況に応じて回復可能または不可能になる可能性があります.

エラーを処理するリアクティブな方法は次のとおりです。

  1. onErrorResumeNextまたはonErrorReturn演算子を介して; これらにより、エラーを検査し、おそらくそれから回復することができます
  2. retry*オペレーターのファミリーを介して; これらにより、エラーを検査し、再サブスクライブすることでエラーから回復できる可能性があります (たとえば、ネットワーク呼び出しを再試行します)。
  3. onErrorサブスクライバーのコールバックを介して; ところで、そのようなコールバックを提供しない場合、エラーは通常の Java 方式で再スローされるため、プログラムクラッシュします。

関連トピック: Retrofit Rx onError でさまざまな種類のエラーを醜い instanceof なしで処理する方法

また、通常の 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ブロックのように機能します。

この件に関するその他のリンク:

于 2017-01-12T08:12:16.147 に答える