2017-06-08 10 views
4

私は、例外処理がどのようにリアクタライブラリで機能するかを理解しようとしています。モノラル非同期例外処理

は、次の例を考えてみましょう:

public class FluxTest { 

@Test 
public void testIt() throws InterruptedException { 
    Scheduler single = Schedulers.single(); 

    CountDownLatch latch = new CountDownLatch(1); 

    Mono.just("hey") 
      .subscribeOn(single) 
      .doOnError(e -> System.out.println("ERROR1: " + e.getMessage())) 
      .doOnTerminate((r, e) -> { 
       if (e != null) System.out.println("ERROR3: " + e.getMessage()); 
       latch.countDown(); 
      }) 
      .subscribe(
        it -> { throw new RuntimeException("Error for " + it); }, 
        ex -> { System.out.println("ERROR2: " + ex.getMessage());} 
        ); 

    latch.await(); 
} 

} 

実は、私はエラーのいずれかが、コードブロックが実行する処理を参照してくださいすることはできません。 テストはメッセージなしで終了します。また、私は運がないdoOnError, doOnTerminateプロセッサを削除しようとしました。

答えて

2

あなたのケースでは正しい動作です。 エラーがない単一の文字列 "hey"からモノを作成しています。デバッグしようとすると、doOnTerminateメソッドがe = nullパラメータで呼び出され、いずれの場合でもドキュメントでは、successまたはerrorが呼び出されることがわかります。あなたは次のことを行うことができます扱ういくつかのエラーをテストする

public class FluxTest { 
    @Test 
    public void testIt() throws InterruptedException { 
     Scheduler single = Schedulers.single(); 

     CountDownLatch latch = new CountDownLatch(1); 

     Mono.just("hey") 
       .map(this::mapWithException) 
       .subscribeOn(single) 
       .doOnError(e -> System.out.println("ERROR1: " + e.getMessage())) 
       .doOnTerminate((r, e) -> { 
        if (e != null) System.out.println("ERROR3: " + e.getMessage()); 
        latch.countDown(); 
       }) 
       .subscribe(
         it -> { throw new RuntimeException("Error for " + it); }, 
         ex -> { System.out.println("ERROR2: " + ex.getMessage());} 
         ); 

     latch.await(); 
    } 

    private String mapWithException(String s) { 
     throw new RuntimeException(); 
    } 
} 

はあなたの上のコードでテストを実行した後、あなたでは3行は

ERROR1: null 
ERROR3: null 
ERROR2: null 

を慰めるべきでモノが失敗したときに最初のコールバックはonErrorですモノはエラーで終了し、第3のものはerrorConsumerからsubscribeメソッドであるため、2番目はonTerminateになります。

+0

yor回答ありがとうございます。だから、sbscriberのエラーを処理する正しい方法は何ですか?それらをサブスクライバコードで処理するだけですか? – mgulimonov

+0

@MaximGulimonovそれは、サブスクライバでいくつかのエラーを処理したい場合は、 'errorConsumer'を指定する必要があります。どんな場合でもエラーを処理したい場合は、' doOnError'メソッドを記述する必要があります。 –

+0

つまり、 'doOnError'のようなFlux構造を使ってサブスクライバコードで発生したエラーを処理できないということです。また、errorConsumer lambdaもそのような例外を処理できません。 – mgulimonov

関連する問題