🤗 ApiHug × {Postman|Swagger|Api...} = 快↑ 准√ 省↓
- GitHub - apihug/apihug.com: All abou the Apihug
- apihug.com: 有爱,有温度,有质量,有信任
- 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
无外乎:
- Catch 返回一个默认的值;
- Catch 然后切换到另外一个
fallback
链路; - Catch 动态计算一个
fallback
返回值; - Catch, 封装成自己的
BusinessException
, 然后 re-throw; - Catch, 打印一个错误日志, 然后 re-throw;
- 类似
try-with-resource
在finally
中释放资源。
这几大类型 reactor 都有类似的处理方式,这里不一一枚举; reactor提供了几种处理error的方法入口:
onErrorReturn
:出现错误直接返回默认值onErrorResume
:出现错误使用备用方案onErrorContinue
:出现错误跳过错误,使用原数据继续执行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