简体   繁体   English

如何<B><A>在出错时</a>从 Mono返回 Mono <B><A>?</a>

[英]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逻辑的旁注:

  1. 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

  2. I have the same argument for B::buildSuccessResponse .我对B::buildSuccessResponse有同样的论点。

  3. 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.

相关问题 从 Mono 调用返回一个值 - Return a value from a Mono call Reactor Mono,如何同步进程(using.map())并返回 Mono<void> 来自 response.setComplete()</void> - Reactor Mono, how to synch process (using .map()) and return Mono<void> from response.setComplete() 当它从数据库中获取任何内容时,如何获取服务层以返回Mono :: error - How to get service layer to return a Mono::error when it fetches nothing from database 如何返回 Mono<ServerResponse> (作为副作用?) Mono.subscribe()? - How to return a Mono<ServerResponse> (as a side effect?) of Mono.subscribe()? 如何立即从Mono.zip返回服务器已发送事件? - How to immediately return Server Sent Events from Mono.zip? 如何有条件地从 WebFilter 中的 Mono 返回? - How do I conditionally return from a Mono within a WebFilter? 如何解决,调用 Mono<token> 然后结果将用于另一个 Mono<collection> ,然后将返回 Mono<collection> ?</collection></collection></token> - How to solve the, calling for Mono<Token> then the result will be used to another Mono<Collection>, which will then return Mono<collection>? 如何从单声道中获取价值 - How to get value from mono 如何从Mono创建Flux - How to create Flux from Mono 单声道 <Mono<Object> &gt;如何订阅 - Mono<Mono<Object>> how to subscribe
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM