使用 rxjava 正确处理所有类型的 Retrofit 错误
Handle all types of Retrofit errors properly with rxjava
我是 Rxjava
和 Retrofit
的新手,我正在寻求使用 rxjava
和 rxbinding
处理 Retrofit 中所有可能状态的最佳正确方法其中包括:
- 没有互联网连接。
- 来自服务器的空响应。
- 响应成功。
- 错误响应并显示错误消息,如
Username or password is incorrect
。
- 其他错误,例如
connection reset by peers
。
我有每个重要失败响应的异常子类。
异常作为 Observable.error()
传递,而值通过流传递,没有任何包装。
1) 没有互联网 - ConnectionException
2) 空 - 只是 NullPointerException
4) 检查 "Bad Request" 并抛出 IncorrectLoginPasswordException
5) 任何其他错误只是 NetworkException
您可以使用 onErrorResumeNext()
和 map()
映射错误
例如
从网络服务获取数据的典型改造方法:
public Observable<List<Bill>> getBills() {
return mainWebService.getBills()
.doOnNext(this::assertIsResponseSuccessful)
.onErrorResumeNext(transformIOExceptionIntoConnectionException());
}
确保响应正常的方法,否则抛出适当的异常
private void assertIsResponseSuccessful(Response response) {
if (!response.isSuccessful() || response.body() == null) {
int code = response.code();
switch (code) {
case 403:
throw new ForbiddenException();
case 500:
case 502:
throw new InternalServerError();
default:
throw new NetworkException(response.message(), response.code());
}
}
}
IOException 意味着没有网络连接所以我抛出 ConnectionException
private <T> Function<Throwable, Observable<T>> transformIOExceptionIntoConnectionException() {
// if error is IOException then transform it into ConnectionException
return t -> t instanceof IOException ? Observable.error(new ConnectionException(t.getMessage())) : Observable.error(
t);
}
为您的登录请求创建新方法来检查 login/password 是否正常。
最后还有
subscribe(okResponse -> {}, error -> {
// handle error
});
我是 Rxjava
和 Retrofit
的新手,我正在寻求使用 rxjava
和 rxbinding
处理 Retrofit 中所有可能状态的最佳正确方法其中包括:
- 没有互联网连接。
- 来自服务器的空响应。
- 响应成功。
- 错误响应并显示错误消息,如
Username or password is incorrect
。 - 其他错误,例如
connection reset by peers
。
我有每个重要失败响应的异常子类。
异常作为 Observable.error()
传递,而值通过流传递,没有任何包装。
1) 没有互联网 - ConnectionException
2) 空 - 只是 NullPointerException
4) 检查 "Bad Request" 并抛出 IncorrectLoginPasswordException
5) 任何其他错误只是 NetworkException
您可以使用 onErrorResumeNext()
和 map()
例如
从网络服务获取数据的典型改造方法:
public Observable<List<Bill>> getBills() {
return mainWebService.getBills()
.doOnNext(this::assertIsResponseSuccessful)
.onErrorResumeNext(transformIOExceptionIntoConnectionException());
}
确保响应正常的方法,否则抛出适当的异常
private void assertIsResponseSuccessful(Response response) {
if (!response.isSuccessful() || response.body() == null) {
int code = response.code();
switch (code) {
case 403:
throw new ForbiddenException();
case 500:
case 502:
throw new InternalServerError();
default:
throw new NetworkException(response.message(), response.code());
}
}
}
IOException 意味着没有网络连接所以我抛出 ConnectionException
private <T> Function<Throwable, Observable<T>> transformIOExceptionIntoConnectionException() {
// if error is IOException then transform it into ConnectionException
return t -> t instanceof IOException ? Observable.error(new ConnectionException(t.getMessage())) : Observable.error(
t);
}
为您的登录请求创建新方法来检查 login/password 是否正常。
最后还有
subscribe(okResponse -> {}, error -> {
// handle error
});