我有下面的代码重新调谐Mono<Foo>
:
try {
return userRepository.findById(id) // step 1
.flatMap(user -> barRepository.findByUserId( user.getId()) // step 2
.map(bar-> Foo.builder().msg("Already exists").build()) // step 3
.switchIfEmpty(barRepository.save(Bar.builder().userId(user.getId()).build()) // step 4
.map(bar-> Foo.builder().msg("Created").build()) // step 5
))
.doOnError(throwable -> Mono.just(handleError(throwable)));
} catch(Exception e) {
log.error("from catch block");
return Mono.just(handleError(e));
}
字符串
如果在步骤1中出现错误(例如用户不存在指定的id),它会被doOnError或try-catch块捕获,还是这两个都不捕获?
如果在步骤2、步骤3、步骤4中发生错误,问题也是一样。
什么是正确的代码,使错误始终被doOnError
捕获并消除try-catch?
我正在使用:
public interface UserRepository extends ReactiveMongoRepository<User, String>
型barRepository
也是如此。handleError(throwable)
简单地执行log.error(e.getMessage())
并重新调谐Foo
。
6条答案
按热度按时间ffvjumwh1#
我认为第一个错误是标题:“Mono or Flux”与错误处理无关。
*Mono最多只能发射一个项目(流一个元素)
*Flux可以发射更复杂的东西(即列表)
要处理错误,您可以遵循以下示例:
字符串
lsmd5eda2#
DoOnError只会产生副作用,假设findById会返回一个Mono.Error(),如果失败的话,类似这样的方法应该可以工作。
字符串
只有当您调用链的阻塞操作,或者在进入React链之前发生运行时错误时,try catch才会起作用。
doOn
操作不修改链,它们仅用于副作用。因为flatMap
需要一个生产者,所以您需要从调用中返回一个Mono,在这种情况下,如果发生错误,那么它只会传播错误。在所有React链中,错误将传播,除非另有处理。r3i60tvu3#
使用
Exceptions.propagate(e)
,它将检查的异常 Package 成可以由onError
处理的特殊运行时异常下面的代码尝试用大写字母覆盖用户属性。现在,当它遇到凯尔时,抛出选中的异常,并从
onErrorReturn
返回MIKE字符串
产出
型
ctehm74n4#
@Gianluca平托的最后一行代码也不正确。代码不会被编译。onErrorReturn不适合复杂的错误处理。你应该使用onErrorResume。
请参阅:https://grokonez.com/reactive-programming/reactor/reactor-handle-error#21_By_falling_back_to_another_Flux
onErrorResume将回退到另一个Flux,并让您捕获和管理由前一个Flux引发的异常。如果查看onErrorReturn的实现,你会发现onErrorReturn实际上使用的是onErrorResume。
所以这里的代码应该是:
字符串
dluptydi5#
@James Ralston的代码的最后一行是错误的。正确的代码应该是:
字符串
qni6mghb6#
在创建React流时,我们需要使用onError*,因为它提供了一个回退Mono/Flux,而杜恩 * 是副作用操作符。
注:示例在Kotlin中
下面是一个例子:
字符串
应该有一个中央异常处理程序,我们可以通过扩展
AbstractErrorWebExceptionHandler
来创建。顺序为-2以取代默认值。下面是一个例子:
型