简体   繁体   English

转换Observable onError并发出一个项目

[英]Transform Observable onError and emit an item

In my Android App I have a generated (Swagger) ApiClient which gets initialized with a Token to identify the User. 在我的Android应用程序中,我有一个生成的(Swagger)ApiClient,它使用令牌进行初始化以标识用户。

This Token (which comes from the Server) can expire. 该令牌(来自服务器)可以过期。

I get Observable´s with Data from my WebService via myApiClient.myServiceMethod(params) 我通过myApiClient.myServiceMethod(params)从我的Web服务中获得了带数据的Observable。

When I get 401 from the Server it means my Token is expired and I have to initialize myApiClient again (to get it with an unexpired Token). 当我从服务器获得401时,这意味着我的令牌已过期,并且我必须再次初始化myApiClient(以使用未过期的令牌获取它)。

How myApiClient is initialized. myApiClient的初始化方式。 It is returned by getMyApiClient() 它由getMyApiClient()返回。

 //getOkHttpClientWithToken() first issues another Server call to get an
 //unexpired Token and then returns an OkHttpClient with that Token set.

 myApiClient = new ApiClient()
              .getAdapterBuilder()
              .baseUrl(url)
              .client(getOkHttpClientWithToken())
              .build()
              .create(MyApiClient.class);

I get the Observable from myApiClient calls 我从myApiClient调用中获得了Observable

Observable<Result> getResultObservable(Type param1, Type param2) {
    return Observable.just(getMyApiClient())
                     .flatMap(myApiClient ->
                        myApiClient.getResult(param1, param2).cache()
                      );
}

What I tried is 我试过的是

//How to recreate myApiClient and Retry call on new myApiClient when an Error occurs
getResultObservable(param1, param2)
  .take(1)
  .subscribe(result -> {
     doSomethingWithResult();
   }
});

Works but is done on every error, not just 401 and may never end 可以工作,但对每个错误(不仅仅是401)都可以完成,并且可能永远都不会结束

I need something like 我需要类似的东西

getResultObservable(param1, param2)
  .take(1)
  .subscribe(result -> {
     doSomethingWithResult();
   }, e -> {
     if(e.getMessage.equals("HTTP 401")) {
         "Transform this Observable to getResultObservable with new myApiClient and emit Result in onNext"
     } else {
       "Other error inform User and stop."
     }      
   }
});

You may use Observable#onErrorResumeNext to provide an fallback-observable. 您可以使用Observable#onErrorResumeNext提供后备可观察的。 You can check the exception for typ and return a fallback-observable, if given condition is met or just wrap the exception with Observable#error. 如果满足给定条件,则可以检查异常的类型,并返回fallback-observable,或者仅将异常包装为Observable#error。

Please have a look at the test, how #onErrorResumNext is used, to provide an fallback-observable, when some exception happens. 请查看测试,如何在发生某些异常时使用#onErrorResumNext来提供备用备用。

  @Test
  void nameX() {
    Observable<String> stringObservable = get();

    Observable<String> fallback$ =
        stringObservable
            .doOnError(s -> System.out.println("fail -> " + s.getMessage()))
            .onErrorResumeNext(
                throwable -> {
                  if (throwable instanceof MyException) {
                    return fallBack().doOnNext(s -> System.out.println("use fallback value " + s));
                  } else {
                    return Observable.error(throwable);
                  }
                });

    fallback$
        .test()
        .assertNotComplete()
        .assertValueCount(1)
        .assertValueAt(0, s -> "Wurst".equals(s));
  }

  private Observable<String> get() {
    return Observable.error(new MyException("Fail"));
  }

  private Observable<String> fallBack() {
    return Observable.just("Wurst").mergeWith(Observable.never());
  }

  private static final class MyException extends Exception {
    MyException(String message) {
      super(message);
    }
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM