转换 Observable onError 并发出一个项目
Transform Observable onError and emit an item
在我的 Android 应用程序中,我有一个生成的 (Swagger) ApiClient,它使用令牌进行初始化以识别用户。
此令牌(来自服务器)可能会过期。
我通过 myApiClient.myServiceMethod(params)
从我的 WebService 中获取带有数据的 Observable
当我从服务器收到 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);
我从 myApiClient 调用中获取 Observable
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."
}
}
});
您可以使用 Observable#onErrorResumeNext 来提供后备观察。如果满足给定条件,您可以检查 typ 和 return 回退可观察的异常,或者用 Observable#error.
包装异常
请看一下测试,#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);
}
}
在我的 Android 应用程序中,我有一个生成的 (Swagger) ApiClient,它使用令牌进行初始化以识别用户。
此令牌(来自服务器)可能会过期。
我通过 myApiClient.myServiceMethod(params)
从我的 WebService 中获取带有数据的 Observable当我从服务器收到 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);
我从 myApiClient 调用中获取 Observable
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."
}
}
});
您可以使用 Observable#onErrorResumeNext 来提供后备观察。如果满足给定条件,您可以检查 typ 和 return 回退可观察的异常,或者用 Observable#error.
包装异常请看一下测试,#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);
}
}