RxJava2 Single已处置后,抛出RuntimeException且未将其捕获 [英] RuntimeException thrown and not caught in RxJava2 Single after it has been disposed

查看:372
本文介绍了RxJava2 Single已处置后,抛出RuntimeException且未将其捕获的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果已丢弃观察者,则不会捕获RxJava2 Single中抛出的RuntimeException,也不会将其发送到Observer的onError()方法。

我知道调用CompositeDisposable.dispose()意味着我的订户的onSuccess或onError方法将不会被调用,但是异常也不应该被忽略吗?而是由于未捕获RuntimeException而导致应用程序崩溃。

A RuntimeException thrown inside an RxJava2 Single is not getting caught and is not getting sent to the Observer's onError() method if the observer has been disposed.
I understand that calling CompositeDisposable.dispose() means that my Subscriber's onSuccess or onError methods won't be called, but shouldn't the exception be ignored too? Instead the application is crashing because the RuntimeException isn't caught.

这里是Single,如果在a之前引发了异常,则带有注释的行会引发RuntimeException。调用.dispose()方法,它会被捕获,并且错误会发送给订阅者,但是如果在调用.dispose()之后引发异常,则应用程序崩溃。

Here is the Single, the line with the comment can throw a RuntimeException, if the exception is thrown before a call to the .dispose() method, it get's caught and the error is sent to the subscriber, but if the exception is thrown AFTER a call to .dispose() the app crashes.

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

Stacktrace:

Stacktrace:

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)


推荐答案

找到了答案:

RxJava 2设计为不会丢失任何错误。因此,当序列结束或被取消时,发射器无处发送错误,因此它被路由到 RxJavaPlugins.onError

与1不同。 x,2.x默认情况下调用 Thread.currentThread()。getUncaughtExceptionHandler()。uncaughtException(),这会使Android应用程序崩溃。

RxJava 2 is designed so that no errors can be lost. So when the sequence ends or gets cancelled the emitter has nowhere to send the error, so it gets routed to the RxJavaPlugins.onError.
Unlike 1.x, 2.x by default calls Thread.currentThread().getUncaughtExceptionHandler().uncaughtException()which crashes an Android app.

来源

类似的stackoverflow问题

在我的情况下,由于订户已被处置,所以我不再关心发射器可能抛出的错误,因此,在调用之前,发射器应检查其是否已被处置。 onError()

In my case, since the subscriber has been disposed I no longer care about the errors that the emitter could throw, so the emitter should check that it has not been disposed of before calling onError()

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

这篇关于RxJava2 Single已处置后,抛出RuntimeException且未将其捕获的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆