1

私はAPIretoriftをヒットし、ユーザーに関連する記事のリストを取得するために使用しています。渡されたトークンが期限切れの場合、API はエラーをスローします。その場合、API を呼び出して新しいトークンを取得する必要があり、再度APIを呼び出す必要があります。getAriclegetArticlerefreshTokengetArticle

 ApiController.createRx().getArticle(token)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({ response -> toast(response.body().url) }, { e ->
                println(e.printStackTrace())
                if(e is HttpException && e.code() in  arrayOf(401,403)){                      
                   //Here I want to call refresh tolken api
                   toast("Auth error")
                }
                else
                   toast(R.string.something_went_wrong)
            })

編集

与えられた答えは何らかの方向性を示しましたが、それらは私の質問に対する直接的な答えではありません。これが解決方法ですが、これはより良いコードにリファクタリングできると思います

ApiController.createRx().getArticle(Preference.getToken())
            .flatMap { value ->
                if (value.code() in arrayOf(403, 401)) {
                    ApiController.refreshToken()
                    ApiController.createRx().getArticle(Preference.getToken())
                } else Observable.just(value)
            }
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({ response -> println("Success") }, { e ->
                e.printStackTrace()
                toast(R.string.something_went_wrong)
            })



fun refreshToken() {
        val token:String?=ApiController.createRx().refreshToken(Preferences.getRefreshToken()).blockingFirst()?.body()?.token
        if (token != null) Preferences.setAuthToken(token)
    }

編集

コードをもう少しきれいなバージョンにリファクタリングしました

Observable.defer { ApiController.createRx().getArticle(Preferences.getToken()) }
            .flatMap {
                if (it.code() in arrayOf(401, 403)) {
                    ApiController.refreshToken()
                    Observable.error(Throwable())
                } else Observable.just(it)
            }
            .retry(1)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({println("Success") }, {
              it.printStackTrace()
              toast(R.string.something_went_wrong)
            })



 fun refreshToken() {
        var token: String? = null
        try {
            token = createRx().refreshToken(Preferences.getRefreshToken()).blockingFirst().body()!!.token
        } catch (e: Exception) {
            throw e
        }
        println("saving token")
        if (token != null) Preferences.setAuthToken(token)
    }

編集

最終的なリファクタリングされたコードについては、私の回答を確認してください

4

4 に答える 4

0

どのようなエラーが表示されますか?. onErrorResumeNext演算子を使用できるようです。

スロー可能オブジェクトを受け取ったこの演算子は、onError でスロー可能オブジェクトの代わりに Observable を返すことができます。

@Test
    public void observableOnErrorResumeException() {
        Integer[] numbers = {0, 1, 2, 3, 4, 5};

        Observable.from(numbers)
                .doOnNext(number -> {
                    if (number > 3) {
                        try {
                            throw new IllegalArgumentException();
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    }

                })
                .onErrorResumeNext(t -> Observable.just(666))
                .subscribe(System.out::println);

    }

ここでさらに例を見ることができますhttps://github.com/politrons/reactive/blob/master/src/test/java/rx/observables/errors/ObservableExceptions.java

于 2017-08-18T07:21:59.313 に答える