如何在RxJava2中处理400响应

时间:2018-04-11 10:12:55

标签: android kotlin rx-java2

我正在努力在RxJava2中正确处理异常。我试图在OkHttp3拦截器内刷新我的令牌,如下所示:

tokenRepository.refreshToken(authStateManager.current.refreshToken!!)
                        .doOnError {
                            Log.w(TAG, "Could not obtain new access token.")

                            authStateManager.signOut()
                        }
                        .subscribe { tokenResponse ->
                            Log.d(TAG, "Obtained new access token: " + tokenResponse.toString())

                            authStateManager.updateAfterTokenResponse(TokenResponse.jsonDeserialize(tokenResponse.toString()), null)

                            token = authStateManager.current.accessToken
                        }

如果刷新令牌有效并且请求返回200,它可以很好地工作。但是如果刷新令牌无效并且我得到一些错误代码(例如400),则执行doOnError块但是它会继续到抛出以下异常的subscribe块:

retrofit2.adapter.rxjava2.HttpException: HTTP 400 
        at retrofit2.adapter.rxjava2.BodyObservable$BodyObserver.onNext(BodyObservable.java:54)
        at retrofit2.adapter.rxjava2.BodyObservable$BodyObserver.onNext(BodyObservable.java:37)
...

我尝试使用onErrorReturnonErrorResumeNext,但我想完全跳过订阅块(它有一个错误,只是记录用户并且不要尝试做任何事情)。可能吗? refreshToken方法返回Single<JsonObject>类型的响应。

2 个答案:

答案 0 :(得分:3)

您不能在订阅中使用onError吗?我喜欢使用RxKotlin。例如,我可以执行以下操作:

.subscribeBy(onSuccess = {
     // do Something in on success
}, onError = {
     // do something in onError
})

所以在你的情况下,它可能是这样的:

tokenRepository.refreshToken(authStateManager.current.refreshToken!!)
    .subscribeBy(onSuccess = {
        Log.d(TAG, "Obtained new access token: " + it.toString())
        authStateManager.updateAfterTokenResponse(TokenResponse.jsonDeserialize(it.toString()), null)
        token = authStateManager.current.accessToken
    }, onError = {
        Log.w(TAG, "Could not obtain new access token.")
        // the variable "it" here is a throwable which means you can determine if it's a RetrofitException and what status code is returned
    })

但是,如果你不想使用RxKotlin,你可以在Kotlin处理你的Rx订阅:

.subscribe({ Log.d(TAG, "Obtained new access token: " + it.toString()) },
           { Log.e(TAG, "Error is ${it.message}") })

您可以在正在使用Log.e的函数的第二部分中处理错误。

答案 1 :(得分:0)

我遇到了同样的问题但我现在修好了。我不知道我的解释是否正确,但似乎doOnError没有处理异常。

您需要使用subscribe() onError作为参数的Consumer方法,并在那里处理错误:

subscribe(Consumer<? super T> onSuccess, Consumer<? super Throwable> onError)

在Java中它看起来像这样:

.subscribe(tokenResponse -> {
                Log.d(TAG, "Obtained new access token: " + tokenResponse.toString());
                authStateManager.updateAfterTokenResponse(TokenResponse.jsonDeserialize(tokenResponse.toString()), null);
                token = authStateManager.current.accessToken;
            }, throwable -> {
                Log.w(TAG, "Could not obtain new access token.");
                authStateManager.signOut();
            }));