Handling http errors in retrofit and okhttp in android application

Viewed 1371

In my android application I have used retrofit and okhttp as shown in below code snippets. The application works well and I am not getting any error during testing and also on production but some times socket timeout exception, sslhandshake exceptions, unknown host exceptions are being logged in by firebase crashalytics as fatal exceptions, which means that application is being crashed when these exceptions are thrown. I have checked with our network team and they have double checked every thing at their end, but issue is still there. Is there a way that I can catch all these exceptions to avoid any fatal crashes. Here is my implementaion

class CoreDataModule {

    @Provides
    fun provideOkHttpClient(): OkHttpClient {
        val interceptor = HttpLoggingInterceptor()
        interceptor.level = HttpLoggingInterceptor.Level.BODY
        val client = OkHttpClient().newBuilder()
            .connectTimeout(15, TimeUnit.SECONDS)
            .readTimeout(90, TimeUnit.SECONDS)
            .writeTimeout(60, TimeUnit.SECONDS)
        if (BuildConfig.DEBUG) {
            client.addInterceptor(interceptor)
        }
        client.addInterceptor { chain ->
            val request = chain.request()
            val response = chain.proceed(request)
            response
        }
        return client.build()
    }


    @Provides
    @Singleton
    fun provideMoshi(): Moshi = Moshi.Builder().build()

    @Provides
    @Singleton
    fun provideMoshiConverterFactory(): MoshiConverterFactory =
        MoshiConverterFactory.create()
}

This is inside Appmodule class

@Singleton
    @Provides
    fun providemyappService(@appAPI okHttpClient: OkHttpClient, converterFactory: MoshiConverterFactory) =
        provideService(okHttpClient, converterFactory, myappApi::class.java)


    @appAPI
    @Provides
    fun providePrivateOkHttpClient(upstreamClient: OkHttpClient): OkHttpClient {
        return upstreamClient.newBuilder().build()
    }


    @Singleton
    @Provides
    fun provideRemoteDataSource(myappService: myappApi) = RemoteDataSource(myappService)

private fun createRetrofit(
        okhttpClient: OkHttpClient,
        converterFactory: MoshiConverterFactory
    ): Retrofit {
        return if (BuildConfig.DEBUG) {
            Retrofit.Builder()
                .baseUrl(BASE_URL_STAGE)
                .client(okhttpClient)
                .addConverterFactory(converterFactory)
                .build()
        } else {
            Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(okhttpClient)
                .addConverterFactory(converterFactory)
                .build()
        }
    }

    private fun <T> provideService(
        okhttpClient: OkHttpClient,
        converterFactory: MoshiConverterFactory, clazz: Class<T>
    ): T {
        return createRetrofit(okhttpClient, converterFactory).create(clazz)
    }

This is inside API end point interface

@POST("Validate/UserValidation")
    @FormUrlEncoded
    suspend fun validateUser(@Field("data") data: String): Response<ValidationResponse>

Here are some crash logs from firebase console

Fatal Exception: java.net.SocketTimeoutException: failed to connect to app.com.pk/123.123.123.124 (port 443) after 15000ms
       at libcore.io.IoBridge.connectErrno(IoBridge.java:191) (Note: Actual fqdn and ip replaced here)
       at libcore.io.IoBridge.connect(IoBridge.java:127)
       at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:201)
       at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:520)
       at java.net.Socket.connect(Socket.java:927)
       at okhttp3.internal.platform.AndroidPlatform.connectSocket(AndroidPlatform.java:73)
       at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:246)
       at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:166)
       at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257)
       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)
       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)
       at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
       at okhttp3.RealCall$AsyncCall.execute(RealCall.java:200)
       at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
       at java.lang.Thread.run(Thread.java:818)

This is another stacktrace

Fatal Exception: java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)
       at libcore.io.IoBridge.maybeThrowAfterRecvfrom(IoBridge.java:629)
       at libcore.io.IoBridge.recvfrom(IoBridge.java:591)
       at java.net.PlainSocketImpl.read(PlainSocketImpl.java:487)
       at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:37)
       at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
       at okio.Okio$2.read(Okio.java:140)
       at okio.AsyncTimeout$2.read(AsyncTimeout.java:237)
       at okio.RealBufferedSource.indexOf(RealBufferedSource.java:358)
       at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:230)
       at okhttp3.internal.http1.Http1Codec.readHeaderLine(Http1Codec.java:215)
       at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:189)
       at okhttp3.internal.connection.RealConnection.createTunnel(RealConnection.java:376)
       at okhttp3.internal.connection.RealConnection.connectTunnel(RealConnection.java:219)
       at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:160)
       at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257)
       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)
       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)
       at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
       at okhttp3.RealCall$AsyncCall.execute(RealCall.java:200)
       at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)

SSL Handshake exception

Fatal Exception: javax.net.ssl.SSLHandshakeException: SSL handshake aborted: ssl=0x7fa29fd100: I/O error during system call, Connection reset by peer
       at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(NativeCrypto.java)
       at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:323)
       at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:319)
       at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:283)
       at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:168)
       at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257)
       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)
       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)
       at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
       at okhttp3.RealCall$AsyncCall.execute(RealCall.java:200)
       at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
       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)

Unknown host exception

Fatal Exception: java.net.UnknownHostException: Unable to resolve host "app.com.pk": No address associated with hostname Note:ACtual FQDN changed here
       at java.net.InetAddress.lookupHostByName(InetAddress.java:424)
       at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
       at java.net.InetAddress.getAllByName(InetAddress.java:214)
       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)
       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)
       at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
       at okhttp3.RealCall$AsyncCall.execute(RealCall.java:200)
       at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
       at java.lang.Thread.run(Thread.java:856)

I am using retrofit_version = "2.6.0"

0 Answers
Related