2017-04-21 147 views
0

RxJava2拋出的RuntimeException單元沒有被捕獲,並且如果觀察者已被拋棄,則不會被髮送到Observer的onError()方法。
我知道調用CompositeDisposable.dispose()意味着我的訂閱者的onSuccess或onError方法將不會被調用,但不應該忽略異常嗎?相反,應用程序崩潰是因爲RuntimeException未被捕獲。RxJava2中拋出並沒有捕獲到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) 
+0

你確定你沒有投入'一些不相關的代碼'? – pvg

回答

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); 
     } 
} 
相關問題