【发布时间】:2021-03-12 20:59:57
【问题描述】:
假设我有一个 id 数组:[9, 8, 7, 6]。
我做了一些处理,一个元素导致抛出异常。我想以自己的方式处理这种情况(比如说记录它),让其他元素顺其自然。
我怎么知道是哪一个?我需要在我的onError 处理中包含这个元素。
Flux.fromArray(myArray)
.flatMap(element -> {
var foo = processMyEl(element);
return anotherProcess(foo); // this returns Mono
})
.onErrorOperator(element -> handleMyError(element)) // this line is what I need
所以,我所看到的,有一个几乎不错的.onErrorContinue((error, obj) ->,它发出一个错误和一个对象。
但是这个obj 不是导致异常的element 而是导致异常的对象。它发生在我的处理方法中,它不必每次都是相同类型的对象。
.onErrorReturn(...) - 不是我想要的
.doOnError(error -> - 没有我的元素的信息
.onErrorResume(error -> - 同上
有人建议我可以创建自己的异常并将元素传递到那里,然后从异常中检索它。但是我应该如何抛出异常呢?
我应该采用旧的 try catch 方法吗:
Flux.fromArray(myArray)
.flatMap(el -> {
try {
var foo = processMyEl(el);
return anotherProcess(foo); // this returns Mono
} catch (Exception e) {
return Mono.error(new MyException(el));
}
})
.onErrorOperator(error -> handleMyError(error.getElement()))
看起来不太好
编辑:
不仅看起来很糟糕,而且还不起作用。异常完全没有被捕获,直接触发doOnTerminate()并停止整个流
更新:
感谢@JEY,我在flatMap 中使用了.onErrorResume()。
我还通过Mono.defer(() -> Mono.just(processMyEl(el))) 将第一个方法转换为反应流。
请注意:使用Mono.defer() 允许我使用onErrorResume,因为Mono.just() cannot signal errors.
最终代码如下所示:
Flux.fromArray(myArray)
.flatMap(element -> Mono.defer(() -> Mono.just(processMyEl(element)))
.onErrorResume(th -> handleMyError(element, th))
)
.flatMap(foo -> anotherProcess(foo)
.onErrorResume(th -> handleMyError(foo, th)
)
地点:
private Mono<> handleMyError(el, th) {
// handling code
return Mono.empty()
}
【问题讨论】:
-
你应该和你一起使用旧的 try-catch 但不要返回 Mono of error 处理你的错误并返回 Mono.empty() 以便你的错误不会在下游看到并且通量会保持消费。
-
是的,我试图将我的逻辑放在 catch 子句中,但代码甚至没有到达那里,只是终止了我的流,仅此而已
-
如果没有到达,说明错误是在别处抛出的。如果没有更多信息,我们将无法提供帮助。
-
不,它被抛出在这两种方法之一中,但由于一种方法返回
Mono- 正如我在问题中提到的那样,并且可以在那里抛出异常,它不会被捕获通过尝试捕获,因为它不再在其范围内 -
你是对的!我还做的是完全摆脱 try catch 并通过
Mono.just(processMyEl(el))转换为反应流,然后像您向他们两个建议的那样应用onErrorResume,随时发布答案,我会接受它;我还将发布我的最终代码
标签: java reactive-programming project-reactor