Let's say i have the following chain:
public Mono<B> someMethod( Object arg ) {
Mono<A> monoA = Mono.just( arg ).flatMap( adapter1::doSomething );
// success chain
return monoA.map( B::buildSuccessResponse );
}
But in case of error i need to return different type of B, let's say, B.buildErrorResponse( a )
. Any onError / doOnError methods can return only original Mono type (A), but not the one I need to return (B). How to return different Mono type in case of error?
答案 0 :(得分:1)
public Mono<B> someMethod( Object arg ) {
Mono<A> monoA = Mono.just( arg ).flatMap( adapter1::doSomething );
return monoA
.map( B::buildSuccessResponse )
.onErrorResume({ Throwable e ->
return Mono.just(B.buildSuccessResponse(e));
}); // if there is no error, `onErrorResume` is effectively doing nothing
}
下面是一个简单的测试,您可以用来测试行为
public static void main(String[] args) {
Mono.just(1)
.doOnNext(x -> {
throw new RuntimeException("some error from previous operation");
}) //comment this out if you want to simulate successful response
.map(String::valueOf)
.onErrorResume(e -> Mono.just("error response"))
.subscribe(System.out::println);
}
答案 1 :(得分:0)
public Mono<B> someMethod(Object arg) {
return Mono.just(arg)
.flatMap(adapter1::doSomething)
.onErrorResume(throwable -> throwable instanceof Exception,
throwable -> Mono.just(B.buildErrorResponse(throwable)))
.map(B::buildSuccessResponse);
}
onErrorResume
将捕获错误信号,如果它被抛入上游并将用新流替换所有该流(上游):Mono.just(B.buildErrorResponse(throwable))
。
关于someMethod
逻辑的附注:
如果出现错误,此方法会发出next
信号,表示error
信号:B.buildErrorResponse(throwable)
。这听起来不错,因为使用someMethod
的人必须了解他从next
(upstream
)收到的someMthod
信号是next
还是{{1}信号error
。相反,让if-condition
返回实际的someMethod
信号,用户将通过识别例如error
中的错误来根据需要对该错误做出反应。
我对onErrorResume
有相同的论据。
可以使用B::buildSuccessResponse
替换以下代码:Mono.just(arg).flatMap(adapter1::doSomething)
。
总而言之,最终的代码将被重构为:
adapter1.doSomething(arg)
答案 2 :(得分:0)
您可能要检出的方法是:onErrorResume(Throwable,Mapper)或onErrorResume(Predicate)
例如,您的代码可能如下所示:
public Mono<B> someMethod( Object arg ) {
Mono monoA = Mono.just( arg ).flatMap( adapter1::doSomething );
return monoA.onErrorResume({ Throwable e ->
return B::buildSuccessResponse
});
}
在这种情况下,onErrorResume将处理从adapter1 :: doSomething发出的任何错误。请记住,当发出错误时-在后续的Monos上将不再调用“ map”,“ flatMap”或任何其他方法,因为错误将被传递,而不是预期的对象。
然后您可以简单地将所有链接看起来像这样:
public Mono<B> someMethod( Object arg ) {
return Mono.just( arg ).flatMap( adapter1::doSomething ).onErrorResume({ Throwable e ->
return B::buildSuccessResponse
});
}
请记住,所有以'do'开头的方法(例如'doOnError')都将执行提供的闭包,而不修改'emited'对象。