【发布时间】:2021-06-08 11:45:22
【问题描述】:
我有一个将数据存储到 couchbase 数组的功能。我在 couchbase 3.0 sdk 中使用响应式集合。
使用以下示例,我可以存储数据,但我在日志中打印了 CasMismatchException。但由于它是预期的,我不希望它被打印出来,我该如何实现呢?
private Consumer<? super Throwable> upsert(String key, String value) {
return e -> {
if (e instanceof CasMismatchException || e instanceof DocumentExistsException) {
defaultCollection // couchbase reactive default colection
.get(key)
.subscribe(
s -> {
List<String> values = new ArrayList<>();
values.addAll(s.contentAs(ArrayList.class));
values.add(value);
defaultCollection
.replace(key, values, ReplaceOptions.replaceOptions().cas(s.cas()))
.doOnError(upsert(key,value))
.subscribe();
});
} else {
LOGGER.error("Error on couch operation on - {}", e);
}
};
}
这段代码打印错误日志,我可以避免吗?
【问题讨论】:
-
您作为副作用订阅并且在订阅中。这是一种巨大的反应式代码气味,因为您破坏了反应式链,因此操作员无法正确地对错误或取消做出反应。尝试使用诸如
onErrorResume之类的错误处理运算符更好地组合您的链。 -
@SimonBaslé,我使用过 onErrorResume,它可以优雅地处理错误,但是当我对此进行负载测试(大约 1000 个并行调用)时,我得到一个 java.util.concurrent.CompletionException 和数据正在丢失。
-
我正在使用 stackoverflow.com/a/60145492/4290096 中建议的 Hooks.onErrorDropped,看起来我可以控制错误日志
标签: java couchbase project-reactor spring-data-couchbase reactive-streams