All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jvmMain.retrofit.deferred.NetworkResponseDeferredCall.kt Maven / Gradle / Ivy

The newest version!
package com.javiersc.resources.networkResponse.retrofit.deferred

import com.javiersc.resources.networkResponse.NetworkResponse
import com.javiersc.resources.networkResponse.isInternetAvailable
import com.javiersc.resources.networkResponse.ktor.emptyHeader
import com.javiersc.resources.networkResponse.retrofit.deferred.handlers.httpExceptionDeferredHandler
import com.javiersc.resources.networkResponse.retrofit.deferred.handlers.responseDeferredHandler
import com.javiersc.resources.networkResponse.utils.hasBody
import com.javiersc.resources.networkResponse.utils.printlnError
import com.javiersc.resources.networkResponse.utils.printlnWarning
import io.ktor.http.HttpStatusCode
import kotlinx.coroutines.CompletableDeferred
import kotlinx.serialization.SerializationException
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Converter
import retrofit2.HttpException
import retrofit2.Response
import java.io.EOFException
import java.io.InterruptedIOException
import java.net.ConnectException
import java.net.UnknownHostException

internal fun  deferredAdapt(
    call: Call,
    errorConverter: Converter,
): CompletableDeferred> {
    val deferred = CompletableDeferred>()

    deferred.invokeOnCompletion { if (deferred.isCancelled) call.cancel() }

    call.enqueue(
        object : Callback {
            override fun onResponse(call: Call, response: Response) {
                response.responseDeferredHandler(errorConverter, deferred)
            }

            override fun onFailure(call: Call, throwable: Throwable) {
                when (throwable) {
                    is UnknownHostException, is ConnectException, is InterruptedIOException ->
                        onCommonConnectionException(deferred)
                    is EOFException -> onEOFException(deferred)
                    is IllegalStateException -> onIllegalStateException(deferred, throwable)
                    is HttpException -> onHttpException(deferred, errorConverter, throwable)
                    is SerializationException ->
                        if (throwable.hasBody) onIllegalStateException(deferred, throwable)
                        else onEOFException(deferred)
                    else -> deferred.complete(NetworkResponse.UnknownError(throwable))
                }
            }
        }
    )
    return deferred
}

private fun  onEOFException(deferred: CompletableDeferred>) {
    printlnWarning(
        """
           | # # # # # # # # # # # # # # WARNING # # # # # # # # # # # # # # # # # # #
           | # Every 2XX response should have a body except 204/205, as the response #
           | # was empty, the response is transformed to Success with code 204 and   #
           | # the headers are lost. The type should be Unit.                        #
           | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
        """.trimMargin()
    )

    @Suppress("UNCHECKED_CAST")
    try {
        deferred.complete(NetworkResponse.Success(Unit as R, HttpStatusCode.NoContent, emptyHeader))
    } catch (e: ClassCastException) {
        printlnError(
            """
               | # # # # # # # # # # # # # # ERROR # # # # # # # # # # # # # # # # # #
               | # NetworkResponse should use Unit as Success type when body is null #
               | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
            """.trimMargin()
        )
        deferred.complete(NetworkResponse.UnknownError(e))
    }
}

private fun  onIllegalStateException(deferred: CompletableDeferred>, throwable: Throwable) {
    printlnError(
        """
           | # # # # # # # # # # # # # # ERROR # # # # # # # # # # # # # # #
           | # Response body can't be serialized with the object provided  #
           | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
        """.trimMargin()
    )
    deferred.complete(NetworkResponse.UnknownError(throwable))
}

private fun  onCommonConnectionException(deferred: CompletableDeferred>) {
    deferred
        .complete(if (isInternetAvailable) NetworkResponse.RemoteNotAvailable else NetworkResponse.InternetNotAvailable)
}

private fun  onHttpException(
    deferred: CompletableDeferred>,
    errorConverter: Converter,
    exception: HttpException,
) = exception.httpExceptionDeferredHandler(errorConverter, deferred)




© 2015 - 2025 Weber Informatics LLC | Privacy Policy