【问题标题】:Why does Mono.doOnError prints error logs为什么 Mono.doOnError 打印错误日志
【发布时间】: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


【解决方案1】:

我使用 Hooks.onErrorDropped 解决了重复打印错误。

 Hooks.onErrorDropped(error -> {
            logger.log(Level.WARNING, "Exception happened:", error);
        });

但是按照 cmets 中的建议,您也可以使用 onErrorResume。我将 onErrorDropped 用于我的具体情况。更详细的解释可以在下面的链接中找到。

【讨论】:

    猜你喜欢
    • 2021-08-12
    • 1970-01-01
    • 2016-12-18
    • 2021-12-13
    • 1970-01-01
    • 2014-02-21
    • 2011-04-08
    • 2020-12-05
    • 1970-01-01
    相关资源
    最近更新 更多