Преобразовать Obserable onError и создать элемент - PullRequest
0 голосов
/ 05 июля 2018

В моем приложении для Android у меня есть сгенерированный (Swagger) ApiClient, который инициализируется токеном для идентификации пользователя.

Срок действия этого токена (с сервера) может истечь.

Я получаю данные Observable с данными из моего WebService через myApiClient.myServiceMethod (params)

Когда я получаю 401 с сервера, это означает, что срок действия моего токена истек, и мне нужно снова инициализировать myApiClient (чтобы получить его с токеном, срок действия которого не истек).

Как инициализируется myApiClient. Возвращается 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);

Я получаю Observable от вызовов myApiClient

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

То, что я пробовал, это

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

Работает, но выполняется при каждой ошибке, а не только 401, и может никогда не закончиться

Мне нужно что-то вроде

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."
     }      
   }
});

1 Ответ

0 голосов
/ 05 июля 2018

Вы можете использовать Observable # onErrorResumeNext, чтобы обеспечить наблюдаемую альтернативу. Вы можете проверить исключение для typ и вернуть наблюдаемую резервную копию, если данное условие выполнено, или просто обернуть исключение ошибкой Observable #.

Пожалуйста, взгляните на тест, как используется #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);
    }
  }
...