即使tryDemo方法抛出NPE,我也无法弄清楚为什么doOnError代码没有得到执行。我试图了解反应式编程中的错误处理,对此我是陌生的
Mono.zip( Mono.fromCallable( ()->tryDemo()), Mono.fromCallable( ()- >tryDemo1()),Mono.fromCallable(()-> tryDemo2() ))
.flatMap( data -> Mono.just( Tuples.of( data.getT1(), data.getT2(),data.getT3() ) ) )
.doOnError( e -> log.error( "Error {}", e.getStackTrace() ) )
.subscribe(T->{log.info("Tuple {}",T.getT2() );});
public Mono<String> tryDemo() {
log.info( "Data--1" );
return Mono.error( NullPointerException::new );
//return Mono.just( "1" );
}
15:56:07.023 [main] INFO com.infosys.rtbm.Test - Data--1
15:56:07.027 [main] INFO com.infosys.rtbm.Test - Tuple MonoJust
答案 0 :(得分:3)
在您的示例中,您返回错误Mono
。这里最棘手的部分是fromCallable
期望您返回标量值。
如果我们查看Mono.fromCallable
的API,就会发现可接受的参数是
public static <T> Mono<T> fromCallable(Callable<? extends T> supplier)
这意味着如果我们的Callable
返回Mono
,我们将得到
Mono<Mono<Object>> monoOfMono = Mono.fromCallable(() ->
Mono.error(NullPointerException::new)
);
因此,如果我们需要产生一个错误,我们必须直接在lambda中抛出该异常
Mono<Object> justMono = Mono.fromCallable(() -> {
throws new NullPointerException()
});
总结一下,Mono.fromCallable
不会尝试检查返回类型是否为流。因此,您的Mono
被认为是正常的标量值,并向下游传播。因此,要解决此问题,您可以执行以下操作:
tryDemo
方法中引发异常:Mono.zip( Mono.fromCallable( ()->tryDemo()), Mono.fromCallable( ()- >tryDemo1()),Mono.fromCallable(()-> tryDemo2() ))
.flatMap( data -> Mono.just( Tuples.of( data.getT1(), data.getT2(),data.getT3() ) ) )
.doOnError( e -> log.error( "Error {}", e.getStackTrace() ) )
.subscribe(T->{log.info("Tuple {}",T.getT2() );});
public String tryDemo() {
log.info( "Data--1" );
throw new NullPointerException();
//return "1";
}
fromCallable
替换为defer
您可以使用fromCallable
运算符来实现您想通过Mono.defer
实现的懒惰,在这种情况下,该运算符期望Mono
是lambda的返回类型。
如果我们查看该操作员的API,我们将观察以下内容
public static <T> Mono<T> defer(Supplier<? extends Mono<? extends T>> supplier);
在这种情况下,我们有Supplier
恰好期望某事Mono
作为返回类型,因此,一旦再次尝试您的初始代码,您将实现预期的行为:
Mono<Object> justMono = Mono.defer(() ->
Mono.error(NullPointerException::new)
);
在这种情况下,一旦供应商退回Mono
,Mono.defere
就会订阅它并收到错误信号:
Mono.zip(
Mono.defer(() -> tryDemo()),
Mono.defer(() -> tryDemo1()),
Mono.defer(() -> tryDemo2())
)
.flatMap(data -> Mono.just(Tuples.of(
data.getT1(),
data.getT2(),
data.getT3()
)))
.doOnError( e -> log.error( "Error {}", e.getStackTrace() ) )
.subscribe(T -> {
log.info("Tuple {}",T.getT2() );
});