Create Extension to convert a Response to a Failure -> expose to other object

This commit is contained in:
Benoit Marty 2019-09-25 10:58:55 +02:00 committed by Benoit Marty
parent 9b91b6ea87
commit ae8bceacba
2 changed files with 52 additions and 37 deletions

View File

@ -16,24 +16,15 @@
package im.vector.matrix.android.internal.network package im.vector.matrix.android.internal.network
import com.squareup.moshi.JsonDataException
import com.squareup.moshi.Moshi
import im.vector.matrix.android.api.failure.ConsentNotGivenError
import im.vector.matrix.android.api.failure.Failure 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.CancellationException import kotlinx.coroutines.CancellationException
import org.greenrobot.eventbus.EventBus
import retrofit2.Call import retrofit2.Call
import retrofit2.Response
import timber.log.Timber
import java.io.IOException import java.io.IOException
internal suspend inline fun <DATA> executeRequest(block: Request<DATA>.() -> Unit) = Request<DATA>().apply(block).execute() internal suspend inline fun <DATA> executeRequest(block: Request<DATA>.() -> Unit) = Request<DATA>().apply(block).execute()
internal class Request<DATA> { internal class Request<DATA> {
private val moshi: Moshi = MoshiProvider.providesMoshi()
lateinit var apiCall: Call<DATA> lateinit var apiCall: Call<DATA>
suspend fun execute(): DATA { suspend fun execute(): DATA {
@ -55,30 +46,4 @@ internal class Request<DATA> {
} }
} }
} }
private fun <T> Response<T>.toFailure(): Failure {
val errorBody = errorBody() ?: return Failure.Unknown(RuntimeException("errorBody() should not be null"))
val errorBodyStr = errorBody.string()
val matrixErrorAdapter = moshi.adapter(MatrixError::class.java)
try {
val matrixError = matrixErrorAdapter.fromJson(errorBodyStr)
if (matrixError != null) {
if (matrixError.code == MatrixError.M_CONSENT_NOT_GIVEN && !matrixError.consentUri.isNullOrBlank()) {
// Also send this error to the bus, for a global management
EventBus.getDefault().post(ConsentNotGivenError(matrixError.consentUri))
}
return Failure.ServerError(matrixError, code())
}
} catch (ex: JsonDataException) {
// This is not a MatrixError
Timber.w("The error returned by the server is not a MatrixError")
}
return Failure.OtherServerError(errorBodyStr, code())
}
} }

View File

@ -18,14 +18,22 @@
package im.vector.matrix.android.internal.network package im.vector.matrix.android.internal.network
import com.squareup.moshi.JsonDataException
import im.vector.matrix.android.api.failure.ConsentNotGivenError
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.suspendCancellableCoroutine import kotlinx.coroutines.suspendCancellableCoroutine
import okhttp3.ResponseBody
import org.greenrobot.eventbus.EventBus
import retrofit2.Call import retrofit2.Call
import retrofit2.Callback import retrofit2.Callback
import retrofit2.Response import retrofit2.Response
import timber.log.Timber
import kotlin.coroutines.resume import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException import kotlin.coroutines.resumeWithException
suspend fun <T> Call<T>.awaitResponse(): Response<T> { internal suspend fun <T> Call<T>.awaitResponse(): Response<T> {
return suspendCancellableCoroutine { continuation -> return suspendCancellableCoroutine { continuation ->
continuation.invokeOnCancellation { continuation.invokeOnCancellation {
cancel() cancel()
@ -41,3 +49,45 @@ suspend fun <T> Call<T>.awaitResponse(): Response<T> {
}) })
} }
} }
/**
* Convert a retrofit Response to a Failure, and eventually parse errorBody to convert it to a MatrixError
*/
internal fun <T> Response<T>.toFailure(): Failure {
return toFailure(errorBody(), code())
}
/**
* Convert a okhttp3 Response to a Failure, and eventually parse errorBody to convert it to a MatrixError
*/
internal fun okhttp3.Response.toFailure(): Failure {
return toFailure(body(), code())
}
private fun toFailure(errorBody: ResponseBody?, httpCode: Int): Failure {
if (errorBody == null) {
return Failure.Unknown(RuntimeException("errorBody should not be null"))
}
val errorBodyStr = errorBody.string()
val matrixErrorAdapter = MoshiProvider.providesMoshi().adapter(MatrixError::class.java)
try {
val matrixError = matrixErrorAdapter.fromJson(errorBodyStr)
if (matrixError != null) {
if (matrixError.code == MatrixError.M_CONSENT_NOT_GIVEN && !matrixError.consentUri.isNullOrBlank()) {
// Also send this error to the bus, for a global management
EventBus.getDefault().post(ConsentNotGivenError(matrixError.consentUri))
}
return Failure.ServerError(matrixError, httpCode)
}
} catch (ex: JsonDataException) {
// This is not a MatrixError
Timber.w("The error returned by the server is not a MatrixError")
}
return Failure.OtherServerError(errorBodyStr, httpCode)
}