0
W/System.err: java.net.UnknownHostException: Unable to resolve host "api.rawg.io": No address associated with hostname
W/System.err:     at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:156)
        at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:103)
        at java.net.InetAddress.getAllByName(InetAddress.java:1152)
        at okhttp3.Dns$1.lookup(Dns.java:40)
        at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:185)
        at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.java:149)
        at okhttp3.internal.connection.RouteSelector.next(RouteSelector.java:84)
        at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:214)
        at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
        at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
W/System.err:     at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
        at okhttp3.RealCall.execute(RealCall.java:92)
        at retrofit2.OkHttpCall.execute(OkHttpCall.java:186)
        at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:45)
        at io.reactivex.Observable.subscribe(Observable.java:10838)
        at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
        at io.reactivex.Observable.subscribe(Observable.java:10838)
        at io.reactivex.internal.operators.flowable.FlowableFromObservable.subscribeActual(FlowableFromObservable.java:29)
        at io.reactivex.Flowable.subscribe(Flowable.java:12978)
        at io.reactivex.internal.operators.flowable.FlowableOnBackpressureLatest.subscribeActual(FlowableOnBackpressureLatest.java:32)
        at io.reactivex.Flowable.subscribe(Flowable.java:12978)
        at io.reactivex.internal.operators.flowable.FlowableDoOnEach.subscribeActual(FlowableDoOnEach.java:50)
        at io.reactivex.Flowable.subscribe(Flowable.java:12978)
        at io.reactivex.Flowable.subscribe(Flowable.java:12924)
        at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82)
        at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
        at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
        at java.util.concurrent.ThreadPoolExecutor.processTask(ThreadPoolExecutor.java:1187)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:929)
W/System.err: Caused by: android.system.GaiException: android_getaddrinfo failed: EAI_NODATA (No address associated with hostname)
W/System.err:     at libcore.io.Linux.android_getaddrinfo(Native Method)
        at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:74)
        at libcore.io.BlockGuardOs.android_getaddrinfo(BlockGuardOs.java:200)
        at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:74)
        at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:135)
        ... 43 more

When application have connection with internet working good but when i have no internet connection my application crash. I want to handle this Exception but anything what i tried not helped :/ . I tried too check if source is not null . I am using Dagger 2 , Retrofit 2, RxJava, viewModel .

  class VideoViewModel : ViewModel {

    private val authApi: AuthApi

    private val games: MediatorLiveData<TopGames> = MediatorLiveData<TopGames>() 

    @Inject
    constructor(authApis: AuthApi) {

        authApi = authApis
    }


    fun authenticateWithId(dates: String) {
        val source: LiveData<TopGames> = LiveDataReactiveStreams.fromPublisher(
            authApi.getTopGames(dates, "-added").doOnError { t-> print("${t.printStackTrace()}  doOnError") }
                .subscribeOn(Schedulers.io())
        )
        games.addSource<TopGames>(source, object : androidx.lifecycle.Observer<TopGames?> {

            override fun onChanged(t: TopGames?) {
                //   Log.d("TAG", "VideoonChanged: $t")
                games.value = t
                games.removeSource(source)
            }
        })
    }



    fun observeGaneInfo(): LiveData<TopGames?>? {
        return games
    }
}

Other class

interface AuthApi {
 
    @GET("/api/games")
    fun getTopGames(
        @Query("dates") dates: String,
        @Query("ordering") ordering: String
    ): Flowable<TopGames>
}
  • It would make more sense to add `onErrorReturn` or some other error handling in the Rx chain. Currently there is no error handling, so on a valid error that is not handed it will crash. Consider mapping to a `Result` class, that will allow errors down the "happy path" and you can evaluate in the observer to give the right UI feedback to the user if unsuccessful. – Mark Keen Jul 02 '20 at 20:09
  • see this post https://stackoverflow.com/questions/44208618/how-to-handle-error-states-with-livedata – Eddy Ferreira Jul 03 '20 at 00:15

2 Answers2

0

Solution :

create data class on State

data class DataWithStates<T>(
        val data: T? = null,
        val states: Throwable? = null
    )

and in my live data i change val source: LiveData to LiveData<DataWithStates> and work perfectly

  fun authenticateWithId(dates: String) {
        val source: LiveData<DataWithStates<TopGames>> = LiveDataReactiveStreams.fromPublisher(
            authApi.getTopGames(dates, "-added").map { lstUser -> DataWithStates(lstUser) }.onErrorReturn { ex -> DataWithStates(states = ex) }
                .subscribeOn(Schedulers.io())
        )

        games.addSource<DataWithStates<TopGames>>(source, object : androidx.lifecycle.Observer<DataWithStates<TopGames>> {

            override fun onChanged(t: DataWithStates<TopGames>) {
                //   Log.d("TAG", "VideoonChanged: $t")
                games.value = t.data
                games.removeSource(source)
            }
        })
    }

helpful Link https://android.developreference.com/article/11762688/RxJava+to+live+data+error+Handling

0

There is no error handling in your rx chain. So you might to want to do something like this.

        val source: LiveData<TopGames> = LiveDataReactiveStreams.fromPublisher(
        authApi.getTopGames(dates, "-added")
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                {
                    games.value = it
                },
                {
                    // error handling goes here
                }
            )
        )

You can have separate LiveData for your error messages, but the more cleaner approach would be to create State class, as mentioned in other replies, so you only have the single source of view state updates.

Also please note that the Disposable return from subscribe method is better to be disposed on ViewModel's onCleared method.

mol
  • 2,348
  • 4
  • 18
  • 34