Как заставить сервисный уровень возвращать Mono::error, когда он ничего не извлекает из базы данных

#java #spring-boot #reactive-programming #couchbase #project-reactor

#java #spring-boot #реактивное программирование #couchbase #проект-реактор

Вопрос:

Я использую этот блок кода для извлечения некоторых данных из Couchbase, но когда ему ничего не удается извлечь, он не вызывает onErrorResume блок. Есть ли способ, которым я могу вызвать этот код onErrorResume , когда ему не удается найти документ, соответствующий ключу?

 return referenceService.getReferenceTable(referenceKey)
    .flatMap(referenceTable -> {
        logger.info("reference table: {}", referenceTable.toString());
        Market market = getMarket(aggregate.getDate(), aggregate.getMarket(), referenceTable);
        aggregate.setMarket(market);
        return Mono.just(aggregate);
    })
    .onErrorResume(e -> {
        logger.info("Error getting reference table");
        return Mono.error(e);
    });
  

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

 @Service("referenceService")
public class CouchbaseReferenceService implements ReferenceService {

    @Autowired
    private ReferenceRepository referenceRepository;

    @Override
    public Mono<ReferenceTable> getReferenceTable(String key) {
        return referenceRepository.getReferenceTable(key);
    }

}
  

Комментарии:

1. Для пояснения, что вы имеете в виду «когда он ничего не извлекает»? Вы имеете в виду, что это пустой список / карта, или это ожидаемое полномасштабное исключение?

2. AFAIK, он ничего не возвращает, включая пустой список или карту. Сценарий заключается в том, что в базе данных не существует документа с указанным ключом, поэтому извлекать нечего. Когда я запускаю end-to-end в этом сценарии, он не вызывает инструкцию logging в блоке flatMap и не вызывает инструкцию logging в блоке onErrorResume.

3. Итак, он возвращает null ?

4. AFAIK да. Но фреймворк предоставляет реализацию репозитория ( extends ReactiveCouchbaseRepository<ReferenceTable, String> ), поэтому я не знаю наверняка

5. Возможно, разбейте get , чтобы посмотреть, что вы получаете до flatmap, чтобы увидеть, получаете ли вы пустой список или нулевой объект.

Ответ №1:

referenceRepository.getReferenceTable(key) возвращает пустое, Mono когда ReferenceTable с заданным key значением не найдено.

Это не условие ошибки с точки зрения репозитория. Чтобы рассматривать пустое значение Mono как условие ошибки, вы можете использовать .switchIfEmpty(Mono.error(...)) в своем потоке.

Вот ваш пример с .switchIfEmpty примененным:

 return referenceService.getReferenceTable(referenceKey)
    .switchIfEmpty(Mono.error(() -> new RuntimeException("No reference table found with key "   referenceKey)))
    .map(referenceTable -> {
        logger.info("reference table: {}", referenceTable.toString());
        Market market = getMarket(aggregate.getDate(), aggregate.getMarket(), referenceTable);
        aggregate.setMarket(market);
        return aggregate;
    })
    .doOnError(e -> logger.info("Error getting reference table", e));
  

Кроме того, я внес два других изменения в ваш пример:

  1. Поскольку ваша .flatMap реализация представляла собой синхронное сопоставление 1 к 1, вы можете использовать .map вместо этого, как я сделал выше.
  2. Поскольку ваша .onErrorResume реализация вернула то же исключение, которое наблюдалось, вы можете использовать .doOnError , как я сделал выше, позволяя исходному исключению продолжать распространяться.