liujingxing / rxhttp

🔥🔥🔥 Based on OkHttp encapsulation, support Kotlin Coroutines、RxJava2、RxJava3; 30s to get started.
https://juejin.im/post/5ded221a518825125d14a1d4
Apache License 2.0
3.76k stars 458 forks source link

怎么打印每一个rxhttp请求onNext和onError抛出的异常 #148

Closed chenyinchao closed 4 years ago

chenyinchao commented 4 years ago

版本: rxhttp : "1.4.0", rxlife : "1.1.0", okhttp : "3.12.6",

RxHttp.get(Url.Api.).add().asQ(Q.class)
            .as(RxLife.asOnMain(context)).subscribe(data -> {
            }, throwable -> {
                ToastUtils.showShort(throwable.getMessage());
            });

在subscribe订阅返回的回调onNext和onError的异常是在RxJavaPlugins.setErrorHandler(throwable -> LogUtils.e(throwable.getMessage()));中统一处理吗?可是不生效啊

我想打印每一个rxhttp请求onNext和onError抛出的异常

liujingxing commented 4 years ago

RxJava的一个重要的设计理念是:不吃掉任何一个异常, 即抛出的异常无人处理,便会导致程序崩溃, 故我们需要通过RxJavaPlugins.setErrorHandler设置全局异常处理,当你没有设置错误回调,或者管道被中断,此时抛出来的异常就会走全局异常回调。

liujingxing commented 4 years ago

把RxHttp的Debug模式打开,出现异常,会有日志打印的。

chenyinchao commented 4 years ago

@liujingxing 这样是有异常日志,但我想把每一个onNext或onError抛出的异常统一用LogUtils打印,我该怎么统一处理呢

liujingxing commented 4 years ago

这个需要配置两个地方 1、全局异常处理RxJavaPlugins.setErrorHandler 2、自定义异常回调,出现异常打印日志即可,可参考Demo的OnError类。

chenyinchao commented 4 years ago

@liujingxing 我不想去修改每一个Rxhttp请求的onNext和onError回调,我只想回调抛异常的时候用LogUtils(可以保存本地)打印每个throwable,该怎么处理?

liujingxing commented 4 years ago

可通过RxJavaPlugins.setOnObservableSubscribe方法,拦截每次的订阅事件,并返回新的观察者,这种方式不需要你去改动每个请求,但依然需要你设置全局异常处理。

chenyinchao commented 4 years ago

@liujingxing 通过setOnObservableSubscribe 重写新的观察者,对RxHttp请求有影响没?我重写后在新的观察者的onError怎么拿不到异常 // 比如我在Rxhttp请求的onNext的回调中写 int a = 1 / 0,我在onError怎么捕获不到这个异常

liujingxing commented 4 years ago

没有影响,贴出你重写的代码。

chenyinchao commented 4 years ago

@liujingxing

请求:
RxHttp.postForm(Url.Api.Login.a).add("a", a).asResultPaser(A.class)
    .as(RxLife.asOnMain(context)).subscribe(aa -> {
        int abc = 1 / 0;
    }, throwable -> {
        ToastUtils.showShort(throwable.getMessage());
    });

Application.java
RxJavaPlugins.setErrorHandler(throwable -> LogUtils.e(throwable.getMessage()));
RxHttp.setDebug(true);
RxJavaPlugins.setOnObservableSubscribe(new BiFunction<Observable, Observer, Observer>() {
    @Override
    public Observer apply(Observable observable, Observer observer) throws Exception {
        return new Observer() {
            @Override
            public void onSubscribe(Disposable d) {
                observer.onSubscribe(d);
            }

            @Override
            public void onNext(Object o) {
                observer.onNext(o);
            }

            @Override
            public void onError(Throwable e) {
                LogUtils.i(e.getMessage());
                observer.onError(e);
            }

            @Override
            public void onComplete() {
                observer.onComplete();
            }
        };
    }
});
liujingxing commented 4 years ago

遗漏了一个细节,这种方式,只能拦截到subscribe上游的异常,对于subscribe传入的回调里发生的异常,是拦截不到的。

chenyinchao commented 4 years ago

@liujingxing 那还是只能用之前的Demo类OnError接口是吧

liujingxing commented 4 years ago

是的,对于你的需求,这是目前最优的解决方案,因为异常只会往下传递。

chenyinchao commented 4 years ago

好的,感谢

liujingxing commented 4 years ago

如果你使用kotlin的话,可以自己扩展subscribe方法,这样,只要出现异常,都能拦截到。