在 Spring webflux 中抛出异常与 Mono.error()

问题描述 投票:0回答:2

我正在开发一个 Spring webflux 项目,我想了解 抛出异常 与使用 Mono.error().

之间的区别

如果有这样的验证类例如:

 public class NameValidator {

   public static boolean isValid(String name) {
     if(StringUtils.isEmpty(name)) {throw new RuntimeException("Invalid name");}
     return true;
  }
}



public class NameValidator2 {

   public static Mono<Object> isValid(String name) {
     if(StringUtils.isEmpty(name)) {
          return Mono.error(new RuntimeException("Invalid name"));}
     return Mono.just(true);

  }

 }

每种方法的优点和缺点是什么。使用 spring webflux 处理反应式流时何时使用其中一种?

java spring spring-boot reactive-programming spring-webflux
2个回答
13
投票

正如@Joao已经说过的,处理错误的推荐方法是在

error
Publisher
/
Mono.error
)上调用
Flux.error
方法。

我想向您展示一个示例,其中传统的

throw
并不像您期望的那样工作:

public void testErrorHandling() {
    Flux.just("a", "b", "c")
        .flatMap(e -> performAction()
            .onErrorResume(t -> {
                System.out.println("Error occurred");
                return Mono.empty();
            }))
        .subscribe();
}

Mono<Void> performAction() {
    throw new RuntimeException();
}

onErrorResume
运算符永远不会被执行,因为在组装
Mono
之前抛出异常。

一般来说,

throw
的工作方式与
Mono.error()
类似(Reactor捕获异常并将其转换为
Mono.error
)。上面的例子不起作用,因为在创建
Mono
之前的组装期间抛出了异常。


4
投票

基本上你最终会得到相同的结果,并且两个选项之间没有区别(也许是性能方面的,但我没有发现任何支持这个观点的东西,所以我想它可以忽略不计。 唯一的“区别”是 Mono.error 遵循 Reactive Streams 规范,并按原样抛出异常(请参阅 https://github.com/reactive-streams/reactive-streams-jvm/blob/v1 了解更多信息)。 0.3/README.md#2.13)。然而,它并没有被禁止,但是如果您喜欢遵循标准和规范(我猜您会这样做),您应该考虑使用 Mono.error。

© www.soinside.com 2019 - 2024. All rights reserved.