[英]How to return Mono<B> from Mono<A> on error?
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 )
.但是如果出现错误,我需要返回不同类型的 B,比如说, B.buildErrorResponse( a )
。 Any onError / doOnError methods can return only original Mono type (A), but not the one I need to return (B).任何 onError / doOnError 方法只能返回原始 Mono 类型 (A),但不能返回我需要返回的类型 (B)。 How to return different Mono type in case of error?出现错误时如何返回不同的 Mono 类型?
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
will catch the error signal if it was thrown in upstream and will replace all that stream (the upstream) with a new stream: Mono.just(B.buildErrorResponse(throwable))
. onErrorResume
将捕获在上游抛出的错误信号,并将用新流替换所有该流(上游): Mono.just(B.buildErrorResponse(throwable))
。
Side note about someMethod
logic:关于someMethod
逻辑的旁注:
In case of an error, this method will signal a next
signal which indicates error
signal: B.buildErrorResponse(throwable)
.如果发生错误,此方法将发出指示error
信号的next
信号: B.buildErrorResponse(throwable)
。 It sounds like a bad idea because who will use someMethod
must understand if the next
signal he received from upstream
( someMthod
) is next
or error
signal by if-condition
.这听起来是个坏主意,因为谁将使用someMethod
必须了解他从upstream
收到的next
信号( someMthod
)是next
还是if-condition
error
信号。 Instead, let someMethod
return the actual error
signal and the user will react to that error as he wants by recognizing the error in, for example, onErrorResume
.相反,让someMethod
返回实际的error
信号,用户将根据需要通过识别错误来对该错误做出反应,例如, onErrorResume
。
I have the same argument for B::buildSuccessResponse
.我对B::buildSuccessResponse
有同样的论点。
The following code can be replaced: Mono.just(arg).flatMap(adapter1::doSomething)
with adapter1.doSomething(arg)
.可以替换以下代码: Mono.just(arg).flatMap(adapter1::doSomething)
与adapter1.doSomething(arg)
。
All in all, the final code will be refactored to:总而言之,最终的代码将重构为:
public Mono<B> someMethod(Object arg) {
return adapter1.doSomething(arg).
}
The methods you might want to check out are: onErrorResume(Throwable, Mapper) or onErrorResume(Predicate)您可能想要检查的方法是: onErrorResume(Throwable, Mapper) 或 onErrorResume(Predicate)
For example your code could look something like this:例如,您的代码可能如下所示:
public Mono<B> someMethod( Object arg ) {
Mono monoA = Mono.just( arg ).flatMap( adapter1::doSomething );
return monoA.onErrorResume({ Throwable e ->
return B::buildSuccessResponse
});
}
In this case the onErrorResume would handle any error emitted from adapter1::doSomething.在这种情况下, onErrorResume 将处理从 adapter1::doSomething 发出的任何错误。 Keep in mind that when an error is emitted - no further 'map', 'flatMap' or any other method is invoked on subsequent Monos since an error will be passed down instead of the expected object.请记住,当发出错误时 - 不会在后续 Monos 上调用进一步的 'map'、'flatMap' 或任何其他方法,因为将传递错误而不是预期的对象。
You could then simply chain it all to look like:然后你可以简单地将它链接起来,看起来像:
public Mono<B> someMethod( Object arg ) {
return Mono.just( arg ).flatMap( adapter1::doSomething ).onErrorResume({ Throwable e ->
return B::buildSuccessResponse
});
}
Keep in mind that all method that start with 'do' like 'doOnError' will execute the closure provided without modifying the 'emitted' object.请记住,所有以 'do' 开头的方法,如 'doOnError' 将执行提供的闭包,而不会修改 'emitted' 对象。
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
}
Below is a simple test which you can use to test the behaviour下面是一个简单的测试,您可以使用它来测试行为
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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.