package im.vector.matrix.android.internal.network import arrow.core.Either import com.squareup.moshi.Moshi import im.vector.matrix.android.api.failure.Failure import im.vector.matrix.android.api.failure.MatrixError import im.vector.matrix.android.internal.di.MoshiProvider import kotlinx.coroutines.Deferred import kotlinx.coroutines.coroutineScope import okhttp3.ResponseBody import retrofit2.Response import java.io.IOException suspend inline fun executeRequest(block: Request.() -> Unit) = Request().apply(block).execute() class Request { var moshi: Moshi = MoshiProvider.providesMoshi() lateinit var apiCall: Deferred> suspend fun execute(): Either = coroutineScope { try { val response = apiCall.await() if (response.isSuccessful) { val result = response.body() Either.Right(result) } else { val failure = manageFailure(response.errorBody()) Either.Left(failure) } } catch (e: Exception) { when (e) { is IOException -> Either.Left(Failure.NetworkConnection(e)) else -> Either.Left(Failure.Unknown(e)) } } } private fun manageFailure(errorBody: ResponseBody?): Failure { return try { val matrixError = errorBody?.let { val matrixErrorAdapter = moshi.adapter(MatrixError::class.java) matrixErrorAdapter.fromJson(errorBody.source()) } ?: throw RuntimeException("Matrix error should not be null") Failure.ServerError(matrixError) } catch (e: Exception) { Failure.Unknown(e) } } }