2017-10-19 135 views
-1

我有一個使用sdk版本25開發的Android項目。我使用RXJava作爲我的線程管理和Retrofit庫來打網絡。SocketTimeoutException由RxJava未處理

我還實現了用於添加重寫有趣攔截(鏈:Interceptor.Chain)的自定義攔截器:響應? {

val request = addHeader(chain) 

    val response = chain.proceed(request) 
    checkErrorResponse(response) 

    return response 

api調用將始終在RX Java流程內,我正在確保它。將我的APK放到Playstore後,Crashlytics檢測到崩潰。

#0. Crashed: main: 0 0 0x0000000000000000 
    at okio.Okio$4.newTimeoutException(Okio.java:230) 
    at okio.AsyncTimeout.exit(AsyncTimeout.java:285) 
    at okio.AsyncTimeout$2.read(AsyncTimeout.java:241) 
    at okio.RealBufferedSource.indexOf(RealBufferedSource.java:345) 
    at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:217) 
    at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:211) 
    at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:189) 
    at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:75) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
    at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
    at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
    at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
    at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
    at com.payfazz.data.base.net.PayfazzInterceptor.intercept(PayfazzInterceptor.kt:24) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185) 
    at okhttp3.RealCall.execute(RealCall.java:69) 
    at retrofit2.OkHttpCall.execute(OkHttpCall.java:180) 
    at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:41) 
    at io.reactivex.Observable.subscribe(Observable.java:10842) 
    at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:33) 
    at io.reactivex.Observable.subscribe(Observable.java:10842) 
    at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:33) 
    at io.reactivex.Observable.subscribe(Observable.java:10842) 
    at io.reactivex.internal.operators.observable.ObservableDefer.subscribeActual(ObservableDefer.java:39) 
    at io.reactivex.Observable.subscribe(Observable.java:10842) 
    at io.reactivex.internal.operators.observable.ObservableDefer.subscribeActual(ObservableDefer.java:39) 
    at io.reactivex.Observable.subscribe(Observable.java:10842) 
    at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96) 
    at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker$BooleanRunnable.run(ExecutorScheduler.java:260) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
    at java.lang.Thread.run(Thread.java:818) 

當我調查stacktrace時,發現我的代碼恰好在我的自定義攔截器中。據我所知,崩潰是由SocketTimeoutException造成的,然後是超時請求。然後我嘗試重現超時但不能完成。在我的環境中,異常總是被RX Java捕獲併發送到onError()方法。

RX Java如何不能捕捉到崩潰?爲了安全起見,我應該使用catch塊來包裝proceed()方法嗎?

+0

您是否找到了解決方法?我遇到同樣的問題,它正在崩潰我的應用程序。 – dazza5000

回答

0

這些類型的崩潰是在RxJava生命週期之外拋出異常時引起的。這意味着你的異常可以通過這兩個選項之一造成的:

  1. retrofit sourcecode去,因此可能會出現Disposable.dispose()被稱爲競態條件,但潛在的Call被取消之前發生超時。這會導致超時被髮送給觀察者後,它已被disposed,觸發崩潰。
  2. onError處理程序中拋出錯誤。這不應該根據RxJava協議發生,並會導致與CompositeException崩潰。由於您發佈的錯誤不包括確切的Exception類,因此不能排除。
+0

以及我認爲第一個問題是,如果在'onError'方法內發生崩潰,堆棧應該顯示'onError'方法內的代碼引起的錯誤。我一定會知道的。關於第一個,你有什麼建議來防止它? –

+0

像這樣的問題很難解決。在Interceptor中爲特定異常添加try-catch可能會暫時解決您的問題,但也可能捕獲應該通過observable的異常。我建議在改進github上打開一個問題,以鏈接到這個問題,這樣可以解決潛在的問題。 或者,你可以爲RxJava的全局異常處理程序創建一個包裝器,以過濾掉這個特定的情況,直到它被修復。請參閱'RxJavaPlugins.setErrorHandler' – Kiskae

相關問題