我正在努力解决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)
...
我尝试使用onErrorReturn
和onErrorResumeNext
,但我想完全跳过订阅块(如果出现错误,只需注销用户,不尝试执行任何操作)。有可能吗?refreshToken
方法返回Single<JsonObject>
类型的响应。
发布于 2018-04-11 18:16:58
你不能在订阅中使用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
的函数的第二部分中处理错误。
发布于 2018-04-12 19:09:04
我刚刚遇到了同样的问题,但我现在解决了它。我不知道我的解释是否正确,但似乎doOnError
没有处理这个异常。
您需要使用接受onError
Consumer
作为参数的subscribe()
方法,并处理那里的错误:
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();
}));
https://stackoverflow.com/questions/49772343
复制相似问题