Retrofit2 + RxJava错误处理

neo*_*ion 3 android rx-java retrofit retrofit2 okhttp3

我正在使用RxJava和Retrofit2(使用OkHttp作为HTTP客户端)进行网络连接,并试图了解Retrofit2如何处理不同的错误以及它们从RxJava方面的外观.以下代码说明了网络调用的RxJava订阅者回调(使用Retrofit进行).

        Subscription subscription = observable
            .subscribeOn(mScheduler)
            .observeOn(mAndroidScheduler)
            .subscribe(new Subscriber<User>() {
                @Override
                public void onCompleted() {
                    Timber.d("onCompleted called");
                    mRetainerView.clearUserObservable();
                    mActivityView.hideProgressBar();
                    mActivityView.enableUi();
                }

                @Override
                public void onError(Throwable e) {
                    Timber.d("onError called");
                    Timber.d(e.toString());
                    mRetainerView.clearUserObservable();
                    mActivityView.hideProgressBar();
                    mActivityView.enableUi();
                }

                @Override
                public void onNext(User user) {
                    Timber.d("onNext called");
                    mRetainerView.clearUserObservable();
                    mActivityView.hideProgressBar();
                    mActivityView.enableUi();
                    mActivityView.launchMainActivity();
                }
            });
Run Code Online (Sandbox Code Playgroud)

我的问题是,在什么情况下会调用onError(),一旦调用它,我如何查询Throwable来确定原因?

从Retrofit源看,可能看到的唯一Throwable是IOException和HttpException.任何人都可以验证这是真的吗?

Ves*_*sko 8

以下是基础知识:onError()如果出现以下情况,将会调用:

  • observable你订阅抛出异常(例如,你得到一个IOException尝试读取文件)
  • 您的onNext()方法中引发异常.

如果你的例外中有例外onComplete(),那么RxJava会传播rx.exceptions.OnCompletedFailedException一个例外,如果有例外onError()- 你会得到rx.exceptions.OnErrorFailedException.

也就是说,您可以Throwable在您的onError()方法中探测您收到的异常情况.例如,您知道如果您的API调用导致客户端错误(4xx),Retrofit会将其包装进去HttpException.如果请求超时,您将得到一个SocketTimeoutException.这是一个粗略的例子:

@Override
public void onError(Throwable e) {
    Timber.d("onError called");
    Timber.d(e.toString());
    handleError(e);
}

private handleError(Throwable throwable) {
    if (throwable instanceof HttpException) {
        HttpException httpException = (HttpException)throwable;
        int statusCode = httpException.code();
        // handle different HTTP error codes here (4xx)
    } else if (throwable instanceof SocketTimeoutException) {
        // handle timeout from Retrofit
    } else if (throwable instanceof IOException) {
       // file was not found, do something
    } else {
       // generic error handling
       mRetainerView.clearUserObservable();
       mActivityView.hideProgressBar();
       mActivityView.enableUi();
}
Run Code Online (Sandbox Code Playgroud)