Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interceptor occasionally not returning callbacks of RxJava #3549

Open
ArcherEmiya05 opened this issue Apr 28, 2021 · 3 comments
Open

Interceptor occasionally not returning callbacks of RxJava #3549

ArcherEmiya05 opened this issue Apr 28, 2021 · 3 comments

Comments

@ArcherEmiya05
Copy link

ArcherEmiya05 commented Apr 28, 2021

I am having trouble with Interceptor as it does not call onError nor onSuccess on specific scenario

This is my interface class

interface EndpointServices {

    companion object {

private fun interceptor(): Interceptor {
            return Interceptor { chain ->
                val request: Request = chain.request()
                val originalResponse: Response = chain.proceed(request)

                originalResponse.newBuilder()
                    .build()

            }
        }


        private fun onlineOfflineHandling(): Interceptor {
            return Interceptor { chain ->
                try {
                    Log.wtf("INTERCEPT", "FETCH ONLINE")
                    val cacheControl = CacheControl.Builder()
                        .maxAge(5, TimeUnit.SECONDS)
                        .build()

                    val response = chain.proceed(chain.request().newBuilder()
                        .removeHeader("Pragma")
                        .removeHeader("Cache-Control")
                        .header("Cache-Control", "public, $cacheControl")
                        .build())

                    Log.wtf("INTERCEPT", "CACHE ${response.cacheResponse} NETWORK ${response.networkResponse}")

                    response
                } catch (e: IOException) {
                    Log.wtf("INTERCEPT", "FALLBACK TO CACHE ${e.message}")

                    val cacheControl: CacheControl = CacheControl.Builder()
                        .maxStale(30, TimeUnit.DAYS)
                        .onlyIfCached() // Use Cache if available
                        .build()

                    val offlineRequest: Request = chain.request().newBuilder()
                        .cacheControl(cacheControl)
                        .build()

                    val response = chain.proceed(offlineRequest)

                    Log.wtf("INTERCEPT", "CACHE ${response.cacheResponse} NETWORK ${response.networkResponse}")

                    response
                }
            }
        }


        fun create(baseUrl: String, cacheDir: File): EndpointServices {

            // Inexact 150 MB of maximum cache size for a total of 4000 assets where 1MB/30 assets
            // The remaining available space will be use for other cacheable requests
            val cacheSize: Long = 150 * 1024 * 1024

            val cache = Cache(cacheDir, cacheSize)

            Log.wtf("CACHE DIRECTORY", cache.directory.absolutePath)

            for (cacheUrl in cache.urls())
                Log.wtf("CACHE URLS", cacheUrl)

            Log.wtf("CACHE OCCUPIED/TOTAL SIZE", "${cache.size()}/${cache.maxSize()}")

            /*val interceptor = HttpLoggingInterceptor()
            interceptor.level = HttpLoggingInterceptor.Level.BODY*/

            val httpClient = OkHttpClient.Builder()
                .cache(cache)
                /*.addInterceptor(interceptor)*/
                .callTimeout(10, TimeUnit.SECONDS)
                .connectTimeout(10, TimeUnit.SECONDS)
                .addNetworkInterceptor(interceptor())
                .addInterceptor(onlineOfflineHandling())
                .build()

            val retrofit = Retrofit.Builder()
                .addCallAdapterFactory(
                    RxJava2CallAdapterFactory.create()
                )
                .addConverterFactory(
                    MoshiConverterFactory.create()
                )
                .client(httpClient)
                .baseUrl(baseUrl)
                .build()

            return retrofit.create(EndpointServices::class.java)

        }

}

@GET("{fullPath}")
    fun getExchangeItems(
        @Path("fullPath", encoded = true) fullPath: String,
        @Query("fields") fields: String
    ):
            Single<ExchangeItemModel>

}

Fetching it with this

private val RetroService by lazy {
        EndpointServices.create(MySingleton.assetLink, application.cacheDir)
    }

RetroService.getExchangeItems(
            MySingleton.exchange.replace("{ID}", assetName.trim().replace(" ", "-")),
            MySingleton.exchangeField
        )
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                { result ->

                    // Filter the item to display
                    includedAsset.value =
                        result.data.filter { it.exchangeName != null && !it.excludedFromPrice}

                    excludedAsset.value =
                        result.data.filter { it.exchangeName != null && it.excludedFromPrice}

                },
                { error ->
                    Log.wtf("WTF", "${error.message}")
                    FirebaseCrashlytics.getInstance().recordException(error)
                    // Only change the UI with this conditions
                    if ((includedAsset.value!!.isEmpty() && excludedAsset.value!!.isEmpty()) || (error is HttpException && error.code() == HttpURLConnection.HTTP_GATEWAY_TIMEOUT))
                        errorMessage.value = R.string.swipe_to_refresh
                }
            ))

Case 1: No network (Wifi/Mobile Data is OFF)

  • Interceptor : A/INTERCEPT: FALLBACK TO CACHE Unable to resolve host "some.host.com": No address associated with hostname

  • onError (error ->) is called if no cache

  • onSuccess (result ->) is called if cache is available

All Good! We show error UI to user during offline mode if no cache exist else we show the list if cache is at least available.

========================================================================

Case 2: Connected to network (Wifi/Mobile Data is ON and the network has INTERNET SERVICE)

  • onError (error ->) is called when response was failed such as 404, etc.

  • onSuccess (result ->) is called when response was success

All Good! BUT due to unknown circumstances sometimes I got
A/INTERCEPT: FALLBACK TO CACHE CANCELED
from the Interceptor and when this happen I don't receive any callbacks neither onError nor onSuccess thus the UI for loading never ends.

========================================================================

Case 3: Connected to network (Wifi/Mobile Data is ON but the network has NO INTERNET SERVICE)

  • Interceptor : A/INTERCEPT: FALLBACK TO CACHE Unable to resolve host "some.host.com": No address associated with hostname

  • onError (error ->) is not called

  • onSuccess (result ->) is not called

As you can see, my Interceptor log here is just the same in our first case yet no callback has been return even a cache is available thus the UI for loading never ends again.

dependencies

implementation 'com.squareup.moshi:moshi-kotlin:1.11.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'

    implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0'

    implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
    // Because RxAndroid releases are few and far between, it is recommended you also
    // explicitly depend on RxJava's latest version for bug fixes and new features.
    // (see https://github.com/ReactiveX/RxJava/releases for latest 3.x.x version)
    implementation 'io.reactivex.rxjava3:rxjava:3.0.0'
@ArcherEmiya05 ArcherEmiya05 changed the title Interceptor not returning callbacks of RxJava Interceptor occasionally not returning callbacks of RxJava Apr 28, 2021
@ArcherEmiya05
Copy link
Author

Any update?

@falgunirana2022
Copy link

Hii @ArcherEmiya05 ,
Did you find any solution to this issue?

@shriharsha-bhagwat
Copy link

@ArcherEmiya05 @falgunirana2022 Do we have any updates for this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants