改装2+RxJava错误处理



我正在使用RxJava和Reformation2(以OkHttp作为HTTP客户端(进行网络连接,并试图了解Reformation 2如何处理不同的错误,以及它们在RxJava方面的外观。以下代码说明了网络调用的RxJava Subscriber回调(使用Reform进行(。

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

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

从Reform源代码来看,似乎只有IOException和HttpException是可以看到的Throwables。有人能证实这是真的吗?

以下是基本信息:如果:,将调用onError()

  • 您订阅的observable引发异常(例如,您在尝试读取文件时获得IOException(
  • 则在onNext()方法中引发异常

如果您的onComplete()中有异常,RxJava将传播一个rx.exceptions.OnCompletedFailedException,如果onError()中有异常-您将获得rx.exceptions.OnErrorFailedException

也就是说,您可以在onError()方法中探测收到的Throwable,以查找您期望的异常。例如,您知道如果您的API调用导致客户端错误(4xx(,那么Reform将把它包装到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();
}

不要将onError用于流。对于流量来说,这将和try-catch一样糟糕。

错误HTTP代码是有效的响应,不应在onError中处理它们。您可以在Result中封装改装服务的返回类型,这使您能够在不引发异常的情况下获得有关调用发生的情况的信息。

您可以使用以下模式处理应用程序的状态:

    service.getSomething()
        .map(r -> Model.success(r.response()))
        .onErrorReturn(Model::error)
        .observeOn(AndroidSchedulers.mainThread())
        .startWith(Resource.loading())
        .subscribe(r -> {
            myProgressBar.setVisible(r.isLoading());
            if (r.isSuccess()) {
                handleSuccess(); // e.g. 400 is also success but needs handling
            }
            if (r.isError()) {
                handleError();
            }
        }, OnErrorNotImplementedException::new);

看看我是如何试图处理流中所有可能的状态的,并故意抛出OnErrorNotImplementedException来寻找我可能错过的东西。这是非常私人的,但我更喜欢快速而愤怒地崩溃,而不是在一段时间内处于未知状态,这将在以后更难调试的崩溃中表现出来。

在Kotlin中,我使用了如下

disposable.add(apiService.getLogin_service(parment1,parment1)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribeWith(object : DisposableSingleObserver<Login_Reg_Data_Model>() {
            override fun onSuccess(model: Login_Reg_Data_Model) {
               //success
            }
            override fun onError(e: Throwable) {  

                if (e is HttpException) {
                    // We had non-200 http error
                    Log.e("time exceptionr******>",e.message)
                } else if (e is SocketTimeoutException) {
                    //time exception
                    Log.e("time exception******>",e.message)
                } else if (e is IOException) {
                    // A network error
                    Log.e("network error******>",e.message)
                } else {
                    //unknown error
                    Log.e("unknown error******>",e.message)
                }

            }
        })
    )

相关内容

  • 没有找到相关文章

最新更新