diff --git a/app/src/main/java/exh/md/handlers/FollowsHandler.kt b/app/src/main/java/exh/md/handlers/FollowsHandler.kt index 508fd6400..2e0d52107 100644 --- a/app/src/main/java/exh/md/handlers/FollowsHandler.kt +++ b/app/src/main/java/exh/md/handlers/FollowsHandler.kt @@ -19,6 +19,7 @@ import exh.md.handlers.serializers.FollowsPageSerializer import exh.md.utils.FollowStatus import exh.md.utils.MdUtil import exh.metadata.metadata.MangaDexSearchMetadata +import exh.util.awaitResponse import exh.util.floor import kotlinx.serialization.decodeFromString import okhttp3.CacheControl @@ -218,16 +219,8 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere headers, CacheControl.FORCE_NETWORK ) - try { - val response = client.newCall(request).await() - followStatusParse(response) - } catch (e: Exception) { - if (e.message.equals("HTTP error 404", true)) { - Track.create(TrackManager.MDLIST).apply { - status = FollowStatus.UNFOLLOWED.int - } - } else throw e - } + val response = client.newCall(request).awaitResponse() + followStatusParse(response) } } } diff --git a/app/src/main/java/exh/util/OkHttpExtensions.kt b/app/src/main/java/exh/util/OkHttpExtensions.kt index b3a0321a2..7271ddc01 100644 --- a/app/src/main/java/exh/util/OkHttpExtensions.kt +++ b/app/src/main/java/exh/util/OkHttpExtensions.kt @@ -1,11 +1,16 @@ package exh.util +import kotlinx.coroutines.suspendCancellableCoroutine import okhttp3.Call +import okhttp3.Callback import okhttp3.Response import rx.Observable import rx.Producer import rx.Subscription +import java.io.IOException import java.util.concurrent.atomic.AtomicBoolean +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException fun Call.asObservableWithAsyncStacktrace(): Observable> { // Record stacktrace at creation time for easier debugging @@ -52,3 +57,32 @@ fun Call.asObservableWithAsyncStacktrace(): Observable subscriber.setProducer(requestArbiter) } } + +/** + * Similar to [Call.await] but it doesn't throw when the response is not successful + */ +suspend fun Call.awaitResponse(): Response { + return suspendCancellableCoroutine { continuation -> + enqueue( + object : Callback { + override fun onResponse(call: Call, response: Response) { + continuation.resume(response) + } + + override fun onFailure(call: Call, e: IOException) { + // Don't bother with resuming the continuation if it is already cancelled. + if (continuation.isCancelled) return + continuation.resumeWithException(e) + } + } + ) + + continuation.invokeOnCancellation { + try { + cancel() + } catch (ex: Throwable) { + // Ignore cancel exception + } + } + } +}