问题描述
我想,以处理在全球范围内的应用程序异常,使改造抛出一个错误我抓住它在一些特定类的逻辑来处理这些错误。
I am trying to handle exceptions in app on global level, so that retrofit throws an error i catch it in some specific class with logic for handling those errors.
我有一个接口
@POST("/token")
AuthToken refreshToken(@Field("grant_type") String grantType, @Field("refresh_token") String refreshToken);
和观测
/**
* Refreshes auth token
*
* @param refreshToken
* @return
*/
public Observable<AuthToken> refreshToken(String refreshToken) {
return Observable.create((Subscriber<? super AuthToken> subscriber) -> {
try {
subscriber.onNext(apiManager.refreshToken(REFRESH_TOKEN, refreshToken));
subscriber.onCompleted();
} catch (Exception e) {
subscriber.onError(e);
}
}).subscribeOn(Schedulers.io());
}
当我得到401从服务器(无效标记或其他网络相关的错误),我想刷新令牌并重复REST调用。有没有办法做到这一点与rxjava所有休息与某种观察到的,将在全球范围赶上这个错误,处理它,并重复抛出-ED的来电信息呢?
When i get 401 from server (invalid token or some other network related error) i want to refresh the token and repeat the rest call. Is there a way to do this with rxjava for all rest calls with some kind of observable that will catch this error globally, handle it and repeat the call that throw-ed it?
现在我使用受捉对.subscribe()这样的错误
For now i am using subject to catch the error on .subscribe() like this
private static BehaviorSubject errorEvent = BehaviorSubject.create();
public static BehaviorSubject<RetrofitError> getErrorEvent() {
return errorEvent;
}
和一些电话
getCurrentUser = userApi.getCurrentUser().observeOn(AndroidSchedulers.mainThread())
.subscribe(
(user) -> {
this.user = user;
},
errorEvent::onNext
);
然后在我的主要活动我订阅的行为主体和解析错误
then in my main activity i subscribe to that behaviour subject and parse the error
SomeApi.getErrorEvent().subscribe(
(e) -> {
//parse the error
}
);
但我不能重复呼吁抛出错误的观测。
but i cant repeat the call for the observable that throw the error.
推荐答案
您需要使用操作符<$c$c>onErrorResumeNext(Func1 resumeFunction) ,在官方维基:
在 onErrorResumeNext()方法返回一个可观察的,反映了源代码的行为观察的,除非观测调用的onError(),在这种情况下,而不是传播的错误给用户,onErrorResumeNext()反而开始镜像第二,备份观测
在你的情况我会把这样的事情:
In your case I would put something like this:
getCurrentUser = userApi.getCurrentUser()
.onErrorResumeNext(refreshTokenAndRetry(userApi.getCurrentUser()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(...)
其中:
private <T> Func1<Throwable,? extends Observable<? extends T>> refreshTokenAndRetry(final Observable<T> toBeResumed) {
return new Func1<Throwable, Observable<? extends T>>() {
@Override
public Observable<? extends T> call(Throwable throwable) {
// Here check if the error thrown really is a 401
if (isHttp401Error(throwable)) {
return refreshToken().flatMap(new Func1<AuthToken, Observable<? extends T>>() {
@Override
public Observable<? extends T> call(AuthToken token) {
return toBeResumed;
}
});
}
// re-throw this error because it's not recoverable from here
return Observable.error(throwable);
}
};
}
还要注意的是这个功能可以很容易地使用在其他情况下,因为它没有输入与由射出的实际值续观测
Note also that this function can be easily used in other cases, because it's not typed with the actual values emitted by the resumed Observable.
这篇关于改造与全球rxjava处理网络异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!