Обработка исключения в реактивных потоках и возвращение значения из предыдущего вызова - PullRequest
0 голосов
/ 02 августа 2020

У меня проблемы с реактивными потоками, и на основании моего кода ниже возвращаемое значение функции должно быть значением, созданным вызовом myServiceConnector.createSummary(request), независимо от того, вызывает ли следующий вызов otherService.postDetails(summary, details, item) исключение или нет. Если он генерирует исключение, я просто хочу вести журнал и в противном случае игнорировать его.

public Mono<Summary> createSummary(final Details details, String authorisation)
{
    return myService.doSomething(details.getItemId(), authorisation)
                       .zipWhen(item -> Mono.just(convertToMyRequest(item, details, myServiceConfig.getBaseRedirectUrl())))
                       .flatMap(tuple -> {
                           MyItem item = tuple.getT1();
                           OrderRequest request = tuple.getT2();
                           return myServiceConnector.createSummary(request)
                                                       .doOnSuccess(summary -> otherService.postDetails(summary, details, item)
                                                                                                            .onErrorContinue((o,i) -> {
                                                                                                                // Log error
                                                                                                            }));

                       });
}

В настоящее время кажется, что вызов onErrorContinue не вызывается (я вызываю исключение otherService.postDetails(summary, details, item) в моем тесте). Я также пробовал onErrorResume, который был вызван, но исключение все еще было выдано, поэтому я не получил возвращенного объекта Summary. Не уверен, что моя обработка ошибок размещена в нужном месте.

Обновление, чтобы включить тестовый код ниже:

@Test
public void returnSummaryWhenOtherServiceFails()
{
    Details details = Details.builder()
                             .itemId(ITEM_ID)
                             .build();

    when(myServiceConfig.getBaseRedirectUrl()).thenReturn(BASE_REDIRECT_URL);
    when(myService.doSomething(ITEM_ID, AUTH_STRING)).thenReturn(Mono.just(ITEM));
    when(myServiceConnector.createSummary(any())).thenReturn(SUMMARY);
    when(otherService.postDetails(any(), any(), any())).thenThrow(WebClientResponseException.class);

    summaryService.createSummary(details, AUTH_STRING).block();
    
    verify(myServiceConnector).createSummary(any());
}

Тест не прошел из-за:

org.springframework.web.reactive.function.client.WebClientResponseException

1 Ответ

0 голосов
/ 04 августа 2020

Если вы хотите вызвать otherService.postDetails в фоновом режиме и не заботитесь о его результате, вы можете сделать это следующим образом:

otherService.postDetails(...).subscribe() 

или

otherService.postDetails(...).publishOn(Schedulers.elastic()).subscribe()

это зависит в вашем коде.

Или вы можете изменить свой код следующим образом:

myServiceConnector.createSummary(request)
.flatMap(summary -> otherService.postDetails(summary, details, item)
    .onErrorContinue(...)
)

он запустит createSummary, а затем postDetails, и если postDetails не сработает, то onErrorContinue будет сработать.

...