使用 rxjava 正确处理所有类型的 Retrofit 错误

ali*_*h95 5 android retrofit2 rx-binding rx-java2

我是新手,我要求最好的正确方法来处理 Retrofit 使用中的所有可能状态,其中Rxjava包括:Retrofitrxjavarxbinding

  1. 没有网络连接。
  2. 来自服务器的空响应。
  3. 成功响应。
  4. 错误响应并显示错误消息,如Username or password is incorrect
  5. 其他错误,例如connection reset by peers.

Tub*_*uby 3

我为每个重要的失败响应都有异常子类。异常以 的形式传递Observable.error(),而值则通过流传递而无需任何包装。

1)没有互联网 - ConnectionException

2) Null - 只是 NullPointerException

4) 检查“错误请求”并抛出 In CorrectLoginPasswordException

5) 任何其他错误都只是 NetworkException

onErrorResumeNext()您可以使用和来映射错误map()

例如

从Web服务获取数据的典型改造方法:

public Observable<List<Bill>> getBills() {
    return mainWebService.getBills()
            .doOnNext(this::assertIsResponseSuccessful)
            .onErrorResumeNext(transformIOExceptionIntoConnectionException());
}
Run Code Online (Sandbox Code Playgroud)

确保响应正常的方法,否则抛出适当的异常

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());
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

对于您的登录请求,创建新方法来检查登录名/密码是否正确。

最后有

subscribe(okResponse -> {}, error -> {
// handle error
});
Run Code Online (Sandbox Code Playgroud)