【问题标题】:Exception Handling in WebFlux publisherWebFlux 发布者中的异常处理
【发布时间】:2022-01-04 02:06:28
【问题描述】:

我想知道为什么下面的 WebFlux 订阅方式不会导致编译错误:

@Test public void handlingSubscriberError() {
        
List l = new ArrayList();
l.add("a");
    Mono.just(l)
          .subscribe(x -> {
           throw new Throwable();
           }, e -> log.error("Error occurred:", e));
}

而这个可以,并建议用 try/catch 块包围:

    @Autowired private PersistenceService writer;

    @Test public void handlingSubscriberError() {
            
    List l = new ArrayList();
    l.add("A");
    Mono.just(l)
       .subscribe(x -> {
       writer.persistTo(x, "B", "C");  <== Unhandled exception type Throwable. 
      }, e -> log.error("Error occurred:", e));
   }

当 Java 编译器仍然强制添加 try-catch 时,将错误使用者作为第二个参数的重载 subscribe() 有什么意义?还是我错过了什么?在 WebFlux 中是否有合适的成语?

【问题讨论】:

  • 第一个 sn-p 确实会导致编译错误,因为Throwable 是 Java 中的已检查异常。
  • 你是说重载的subscribe() 只能用于处理RuntimeExceptions,即使它的签名明确指出参数继承自Throwable

标签: java spring-boot reactive-programming spring-webflux project-reactor


【解决方案1】:

您不能从订阅者那里抛出已检查的异常(例如ThrowableIOException)。 subscribe() 方法采用 Consumer 函数,没有任何异常声明。但是,Reactor 提供了Exceptions 实用程序类,它可以将任何已检查的异常包装成未检查的异常,如下所示:

Mono.just("test")
    .subscribe(x -> {
        try {
            throw new Throwable("Error occurred:");
        } catch (Throwable e) {
            throw Exceptions.propagate(e);
        }
    }, e -> log.error("Error occurred: ", Exceptions.unwrap(e)));

Exception.unwrap 用于获取原始检查异常。

【讨论】:

    猜你喜欢
    • 2021-11-12
    • 2019-03-11
    • 1970-01-01
    • 1970-01-01
    • 2018-06-06
    • 2011-03-06
    • 2020-03-23
    • 1970-01-01
    • 2011-02-25
    相关资源
    最近更新 更多