#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));
Кроме того, я внес два других изменения в ваш пример:
- Поскольку ваша
.flatMap
реализация представляла собой синхронное сопоставление 1 к 1, вы можете использовать.map
вместо этого, как я сделал выше. - Поскольку ваша
.onErrorResume
реализация вернула то же исключение, которое наблюдалось, вы можете использовать.doOnError
, как я сделал выше, позволяя исходному исключению продолжать распространяться.