【问题标题】:RuntimeException thrown and not caught in RxJava2 Single after it has been disposedRuntimeException 在处理后被抛出并且没有在 RxJava2 Single 中被捕获
【发布时间】:2017-04-21 00:33:36
【问题描述】:

RxJava2 Single 中抛出的 RuntimeException 不会被捕获,并且如果观察者已被释放,则不会被发送到观察者的 onError() 方法。
我知道调用 CompositeDisposable.dispose() 意味着不会调用我的订阅者的 onSuccess 或 onError 方法,但不应该也忽略异常吗?相反,应用程序正在崩溃,因为未捕获 RuntimeException。

这里是Single,带注释的那一行可以抛出RuntimeException,如果在调用.dispose()方法之前抛出异常,会被捕获并将错误发送给订阅者,但是如果异常在调用 .dispose() 后引发应用程序崩溃。

public Single<Submission> getSubmission(final String threadId, final CommentSort sort) {
        return Single.create(new SingleOnSubscribe<Submission>() {
            @Override
            public void subscribe(SingleEmitter<Submission> e) throws Exception {
                // some irrelevant code

                try {
                    submission = reddit.getSubmission(sr); // Can throw RuntimeException
                    e.onSuccess(submission);
                } catch (Exception ex) {
                    e.onError(ex);
                }
            }
        });
    }  

我订阅的代码:

disposables.add(someCompletable
                .andThen(service.getSubmission(threadId, CommentSort.HOT))
                .subscribeOn(schedulerProvider.io())
                .observeOn(schedulerProvider.ui())
                .subscribeWith(new DisposableSingleObserver<Submission>() {
                    @Override
                    public void onSuccess(Submission submission) {
                        // Handle result
                    }

                    @Override
                    public void onError(Throwable e) {
                        // Handle error
                    }
                })
        );

堆栈跟踪:

E/AndroidRuntime: FATAL EXCEPTION: RxCachedThreadScheduler-2
Process: com.gmail.jorgegilcavazos.ballislife.debug, PID: 15242
java.lang.RuntimeException: Unable to parse JSON: [{"kind": "Listing", "data": {"modhash": null, "children": [{"kind": "t3", "data
at net.dean.jraw.util.JrawUtils.fromString(JrawUtils.java:182)
at net.dean.jraw.http.RestResponse.<init>(RestResponse.java:64) 
at net.dean.jraw.http.OkHttpAdapter.execute(OkHttpAdapter.java:81)
at net.dean.jraw.http.RestClient.execute(RestClient.java:120)
at net.dean.jraw.RedditClient.execute(RedditClient.java:143)
at net.dean.jraw.RedditClient.execute(RedditClient.java:137)
at net.dean.jraw.RedditClient.getSubmission(RedditClient.java:287)
at com.gmail.jorgegilcavazos.ballislife.network.API.RedditService$10.subscribe(RedditService.java:311)
at io.reactivex.internal.operators.single.SingleCreate.subscribeActual(SingleCreate.java:39)
at io.reactivex.Single.subscribe(Single.java:2656)
at io.reactivex.internal.operators.single.SingleDelayWithCompletable$OtherObserver.onComplete(SingleDelayWithCompletable.java:70)
at io.reactivex.internal.disposables.EmptyDisposable.complete(EmptyDisposable.java:67)
at io.reactivex.internal.operators.completable.CompletableEmpty.subscribeActual(CompletableEmpty.java:27)
at io.reactivex.Completable.subscribe(Completable.java:1592)
at io.reactivex.internal.operators.single.SingleDelayWithCompletable.subscribeActual(SingleDelayWithCompletable.java:36)
at io.reactivex.Single.subscribe(Single.java:2656)

【问题讨论】:

  • 你确定你没有输入“一些不相关的代码”吗?

标签: java android exception rx-java2


【解决方案1】:

找到答案:

RxJava 2 被设计成不会丢失任何错误。因此,当序列结束或被取消时,发射器无处可发送错误,因此它被路由到RxJavaPlugins.onError
与 1.x 不同,2.x 默认调用 Thread.currentThread().getUncaughtExceptionHandler().uncaughtException(),这会导致 Android 应用崩溃。

Source
Similar stackoverflow question

在我的例子中,由于订阅者已经被释放,我不再关心发射器可能抛出的错误,所以发射器在调用onError()之前应该检查它是否没有被释放

try {
      Submission submission = redditClient.getSubmission(sr);
      e.onSuccess(submission);
} catch (Exception ex) {
      if (!e.isDisposed()) {
           e.onError(ex);
      }
}

【讨论】:

    猜你喜欢
    • 2019-01-15
    • 2012-06-06
    • 1970-01-01
    • 2020-08-07
    • 2016-06-08
    • 2017-11-01
    • 1970-01-01
    • 2016-04-04
    • 1970-01-01
    相关资源
    最近更新 更多