Reactor 错误处理-响应式编程-006

🤗 ApiHug × {Postman|Swagger|Api...} = 快↑ 准√ 省↓

  1. GitHub - apihug/apihug.com: All abou the Apihug   
  2. apihug.com: 有爱,有温度,有质量,有信任
  3. ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace

在响应式的流里面, 当一个错误发生时候, 错误便是终结事件, 她导致序列的停滞, 错误向下游扩散, 直到你的 Subscriber 的方法 onError 被调用。

这些错误还是需要反馈到应用层, 比如在页面显示合适的警告, 所以在 subscriber 上来最好定义 onError 回调,以截获和合理的处理这些错误。

如果没有定义呢? 会抛出 UnsupportedOperationException 异常, 也可以通过 Exceptions.isErrorCallbackNotImplemented:

@Test
public void test_case1_no_handle_error() {
  Flux.just(1, 2, 0)
      .map(i -> "100 / " + i + " = " + (100 / i)) // this triggers an error with 0
      .subscribe(System.out::println);
  // Exceptions.isErrorCallbackNotImplemented()
}

获得输出如下:

ERROR reactor.core.publisher.Operators - Operator called default onErrorDropped
reactor.core.Exceptions$ErrorCallbackNotImplemented: java.lang.ArithmeticException: / by zero
Caused by: java.lang.ArithmeticException: / by zero

这里需要强调, 任何流中错误都会导致一个终止事件!

虽然你定义了错误处理的回调, 让整个流 resume或者fallback, 但是他们的作用仅仅是 把 onError 信号转换成一个新的 sequence

也就是从上游, 将已近终止的 sequence 替换掉, 让下游看起来,整个流还在正常的进行中。

#错误处理

诚如我们处理一般的 try-catch 无外乎:

  1. Catch 返回一个默认的值;
  2. Catch 然后切换到另外一个fallback链路;
  3. Catch 动态计算一个 fallback 返回值;
  4. Catch, 封装成自己的 BusinessException, 然后 re-throw;
  5. Catch, 打印一个错误日志, 然后 re-throw;
  6. 类似 try-with-resource 在 finally 中释放资源。

这几大类型 reactor 都有类似的处理方式,这里不一一枚举; reactor提供了几种处理error的方法入口:

  1. onErrorReturn:出现错误直接返回默认值
  2. onErrorResume:出现错误使用备用方案
  3. onErrorContinue:出现错误跳过错误,使用原数据继续执行
  4. onErrorMap:替换错误内容

#onErrorReturn

错误信息替换为指定内容:

@Test
public void onErrorReturn() {
  Flux.interval(Duration.ofMillis(100))
      .map(
          i -> {
            if (i == 2) throw new RuntimeException("fake a mistake");
            return String.valueOf(100 / (i - 5));
          })
      .doOnError(e -> log.error("error 类型:{}, error 消息: {}", e.getClass(), e.getMessage()))
      // 遇到error直接返回指定value, 错误类型判断可选
      .onErrorReturn("test on error return")
      .subscribe(log::info);

  try {
    Thread.sleep(2000);
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
}

输出如下结果:

INFO  com.dearxue.ExceptionTest - -20
INFO  com.dearxue.ExceptionTest - -25
ERROR com.dearxue.ExceptionTest - error 类型:class java.lang.RuntimeException, error 消息&#x
  • 30
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值