web-dev-qa-db-ja.com

Flux.map()の実行中にエラーを処理する方法

Flux内の要素をマッピングするときにエラーを処理する方法を理解しようとしています。

たとえば、CSV文字列を私のビジネスPOJOの1つに解析しています。

myflux.map(stock -> converter.convertHistoricalCSVToStockQuotation(stock));

この行の一部にエラーが含まれている可能性があるため、ログに表示されるのは次のとおりです。

 reactor.core.publisher.FluxLog:  onNext([SOME_BOGUS_QUOTE]@38.09 (Fri Apr 08 00:00:00 CEST 2016) H(38.419998)/L(37.849998)/O(37.970001))
 reactor.core.publisher.FluxLog:  onNext([SOME_BOGUS_QUOTE]@38.130001 (Thu Apr 07 00:00:00 CEST 2016) H(38.189999)/L(37.610001)/O(37.799999))
 reactor.core.publisher.FluxLog:  onError(Java.lang.IllegalArgumentException: Invalid CSV stock quotation: SOME_BOGUS_QUOTE,trololo)
 reactor.core.publisher.FluxLog:  Java.lang.IllegalArgumentException: Invalid CSV stock quotation: SOME_BOGUS_QUOTE,trololo

私はAPIでいくつかのエラー処理メソッドを読みましたが、ほとんどは「エラー値」を返すか、次のようなフォールバックFluxを使用することを指していました。

Flux.onErrorResumeWith(myflux, x -> Mono.fromCallable(() -> ... do stuff);

ただし、これをmy myfluxで使用すると、フラックス全体が再度処理されます。

それで、特定の要素の処理中にエラーを処理し(つまり、それらを無視/ログに記録)、残りのフラックスを処理し続ける方法はありますか?

@ akarnokd回避策を使用したUPDATE

public Flux<StockQuotation> getQuotes(List<String> tickers)
{
    Flux<StockQuotation> processingFlux = Flux.fromIterable(tickers)
    // Get each set of quotes in a separate thread
    .flatMap(s -> Mono.fromCallable(() -> feeder.getCSVQuotes(s)))
    // Convert each list of raw quotes string in a new Flux<String>
    .flatMap(list -> Flux.fromIterable(list))
    // Convert the string to POJOs
    .flatMap(x -> {
            try {
                return Flux.just(converter.convertHistoricalCSVToStockQuotation(x));    
            }
            catch (IllegalArgumentException ex){
                System.out.println("Error decoding stock quotation: " + x);
                return Flux.empty();
            }
    });

    return processingFlux;
}

ただし、コードが以前ほど洗練されていないことがわかるので、これは魅力的に機能します。 Flux APIには、このコードが実行する方法はありませんか?

retry(...)
retryWhen(...)
onErrorResumeWith(...)
onErrorReturn(...)
26
Victor

代わりにflatMapが必要です。これにより、処理が失敗した場合に空のシーケンスを返すことができます。

myflux.flatMap(v -> {
    try {
        return Flux.just(converter.convertHistoricalCSVToStockQuotation(stock));
    } catch (IllegalArgumentException ex) {
        return Flux.empty();
    }
});
20
akarnokd

Reactor 3のメソッドを使用して例外を処理する場合は、Mono.fromCallableを使用できます。

flatMap(x -> 
    Mono.fromCallable(() -> converter.convertHistoricalCSVToStockQuotation(x))
        .flux()
        .flatMap(Flux::fromIterable)
        .onErrorResume(Flux::empty)
)

残念ながらFlux.fromCallableがないため、呼び出し可能オブジェクトがリストを返すと想定して、手動でFluxに変換する必要があります。

14

Reactor 3の現在のバージョンでは、かなり多くのメソッドが追加されています。したがって、次のようにすることができます。

Flux.onErrorResume(error -> { 
        System.out.println("Error decoding stock quotation: " + e);
        return Flux.empty();
    });

エラーの処理方法に関する詳細情報を参照 ここ

5
code4kix

OnErrorContinueを使用できます。トラブル要素を削除して後続の要素を続行することで、エラーから回復できます。

2
seanzxx