I recently updated Retrofit to 2.7.0
and OKHttp to 3.14.4
to take advantage of suspend fun on Retrofit interfaces.
Besides that, I'm also trying to implement Authenticator for the refresh token logic.
This is the retrofit interface
interface OfficeApi {
@Authenticated
@POST
suspend fun getCharacter(): Response<CharacterResponse>
}
This is my Authenticator
class CharacterAuthenticator : Authenticator {
override fun authenticate(
route: Route?,
response: Response
): Request? {
if (responseCount(response) >= 2) return null
return response.request()
.newBuilder()
.removeHeader("Authorization")
.addHeader("Authorization", "Bearer $newToken")
.build()
return null
}
private fun responseCount(response: Response?): Int {
var result = 1
while (response?.priorResponse() != null) result++
return result
}
}
This is the retrofit fun call
override suspend fun getCharacter() = safeApiCall(moshiConverter) {
myApi.getCharacter()
}
This is the safeApiCall
:
suspend fun <T> safeApiCall(
moshiConverter: MoshiConverter,
apiCall: suspend () -> Response<T>
): Result<T?, ResultError.NetworkError> {
return try {
val response = apiCall()
if (response.isSuccessful) Result.Success(response.body())
else {
val errorBody = response.errorBody()
val errorBodyResponse = if (errorBody != null) {
moshiConverter.fromJsonObject(errorBody.string(), ErrorBodyResponse::class.java)
} else null
Result.Error(
ResultError.NetworkError(
httpCode = response.code(),
httpMessage = response.message(),
serverCode = errorBodyResponse?.code,
serverMessage = errorBodyResponse?.message
)
)
}
} catch (exception: Exception) {
Result.Error(ResultError.NetworkError(-1, exception.message))
}
}
The Authenticator is working properly, trying to refresh the token twice and then giving up. The problem is: when it gives up (return null), the execution of retrofit (safeApiCall
function) does not continue. I don't have any feedback if the call was successful or not.
Is there any problem using Authenticator and Coroutines suspend fun
?
Isn't this an infinite loop?
while (response?.priorResponse() != null)
Shouldn't it be
var curResponse: Response? = response
while (curResponse?.priorResponse() != null) {
result++
curResponse = curResponse.priorResponse()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With