Freddy Daniel
Freddy Daniel

Reputation: 389

I can't handle the retrofit exception when there is no internet connection

I'm did one app which is consuming one api. I can search dogs by breed using this endpoint: https://dog.ceo/api/breed/labrador/images where {labrador} is the breed. The app works fine when there is internet connection or wifi. But when there is no internet, the retrofit library is throwing an exception:

Process: com.example.retrofitrecyclerviewkotlin, PID: 11879
    javax.net.ssl.SSLHandshakeException: SSL handshake aborted: ssl=0xa4b28280: I/O error during system call, Connection reset by peer
        at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
        at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:362)
        at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:336)
        at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:300)
        at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:185)
        at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.java:224)
        at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.java:108)
        at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.java:88)
        at okhttp3.internal.connection.Transmitter.newExchange(Transmitter.java:169)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:41)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:94)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:88)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:229)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:172)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at java.lang.Thread.run(Thread.java:761)

This is my code that where I should fix this problem:

    private fun getRetrofit():Retrofit {

            return Retrofit.Builder()
                    .baseUrl("https://dog.ceo/api/breed/")
                    .addConverterFactory(GsonConverterFactory.create()) //convert the json to DogResponse
                    .build()
    }

 private fun searchByRaza(query:String){
            CoroutineScope(Dispatchers.IO).launch {
                val call = getRetrofit().create(ApiService::class.java).getDogsByRaza("$query/images")
                var perros = call.body() 
                
                runOnUiThread {
                    if (call.isSuccessful) {
                        val images = perros?.images ?: emptyList()
                        dogImages.clear()
                        dogImages.addAll(images)
                       
                        adapter.notifyDataSetChanged()
                    } else {
                        
                        showError()
                    }
                }
            }

    }

I think that the problem is inside of the method getRetrofit() I tried to add one try-catch to handle the exception but I only got erros:

 private fun getRetrofit():Retrofit {
        try {
            return Retrofit.Builder()
                    .baseUrl("https://dog.ceo/api/breed/")
                    .addConverterFactory(GsonConverterFactory.create()) //convertir el json a DogResponse
                    .build()

        }catch (e: Exception){
          return  null
        }
     }

It says: Null can not be a value of a non-null type Retrofit Any idea to fix this problem guys I will appreciate it. I would like to show a message to the user alerting about of the lack of internet connection. thanks so much.

Upvotes: 0

Views: 712

Answers (2)

Javier Aravena
Javier Aravena

Reputation: 1

I have something similar with another API, Maybe you need to add the .execute() at the end of var perros. Like this:

val call = getRetrofit().create(APIService::class.java).getCharacterByName("$query").execute()

and add a casting val employees = call.body() as EmployeeResponse

Upvotes: 0

Yunis Rasulzade
Yunis Rasulzade

Reputation: 385

You can use try/catch block in order to catch exception.

  CoroutineScope(Dispatchers.IO).launch {
            val call = getRetrofit().create(ApiService::class.java).getDogsByRaza("$query/images")
            try {
                var perros = call.body()
            } catch (exc: Exception) {
                withContext(Dispatchers.Main) {
                    Log.d(TAG, "test: "+exc)
                    //show toast in main thread
                }
            }
        }
  

Upvotes: 1

Related Questions