doc: Exceptions.propagate文档阅读

This commit is contained in:
asahi
2025-04-15 12:45:54 +08:00
parent b69bd6cdd8
commit 1d858eb6c1

View File

@@ -64,6 +64,8 @@
- [retry helper](#retry-helper)
- [retrying with transient errors](#retrying-with-transient-errors)
- [handling Exceptions in operators or functions](#handling-exceptions-in-operators-or-functions)
- [checked exception](#checked-exception)
- [Exceptions Utility](#exceptions-utility)
>>>>>>> 8d41980 (doc: 阅读transient errors文档)
# Reactor
@@ -992,3 +994,62 @@ assertThat(errorCount).hasValue(6);
> `transientErrors`主要是为了处理周期性发生异常,异常能够重试成功,并且发生异常后一段时间平稳运行的场景
#### handling Exceptions in operators or functions
通常来说operator的执行有可能会抛出异常根据抛出异常类型的不同存在如何区别
- `unchecked Exception`:对于抛出的`unchecked exception`,其都会通过`onError`向下游传递例如map operator中抛出的`RuntimeException`将会被转化为对下游`onError`的调用
```java
Flux.just("foo")
.map(s -> { throw new IllegalArgumentException(s); })
.subscribe(v -> System.out.println("GOT VALUE"),
e -> System.out.println("ERROR: " + e));
```
上述代码示例将会触发下游subscriber的onError输出内容如下
```console
ERROR: java.lang.IllegalArgumentException: foo
```
- `fatal exceptions`在reactor中定义了一些被视为`致命`的异常(例如`OutOfMemoryError`),具体的`fatal`异常包含范围可见`Exceptions.throwIfFatal`
- 在抛出`fatal error`时reactor operator会抛出异常而不是将其传递到下游
##### checked exception
对于`checked exception`,当调用方法签名中指定了`throws xxxException`的方法时,需要通过`try-catch block`对其进行处理。对于`checked exception`,有如下选择:
- 对异常进行捕获,并且对其执行`recover`操作sequence会继续执行
- 对异常进行捕获,并且封装到`unchecked exception`中,并将`unchecked exception`进行rethrow(这将对sequence进行打断)
- 如果需要返回一个`Flux`(例如,使用`flatMap`方法),可以使用`Flux.error(checkedException)`返回一个`error-producing Flux`sequence会终止
##### Exceptions Utility
通过reactor提供的Exceptions Utility可以保证`仅当异常为checked exception时才会封装`
- `Exceptions.propagate`在必要时会封装exception。
- 其并不会对`RuntimeException`进行封装,并且该方法首先会调用`throwIfFatal`
- 该方法会将checked exception封装到`reactor.core.Exceptions.ReactiveException`中
- `Exceptions.unwrap`
- 该方法会获取original unwrapped exception
使用示例如下所示:
```java
public String convert(int i) throws IOException {
if (i > 3) {
throw new IOException("boom " + i);
}
return "OK " + i;
}
Flux<String> converted = Flux
.range(1, 10)
.map(i -> {
try { return convert(i); }
catch (IOException e) { throw Exceptions.propagate(e); }
});
converted.subscribe(
v -> System.out.println("RECEIVED: " + v),
e -> {
if (Exceptions.unwrap(e) instanceof IOException) {
System.out.println("Something bad happened with I/O");
} else {
System.out.println("Something bad happened");
}
}
);
```