package com.illusionman1212.lyricsgrabbr.utils import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.suspendCancellableCoroutine import okhttp3.Call import okhttp3.Response import okhttp3.Callback import okio.IOException import kotlin.coroutines.resumeWithException // Based on https://github.com/gildor/kotlin-coroutines-okhttp @OptIn(ExperimentalCoroutinesApi::class) private suspend fun Call.await(callStack: Array): Response { return suspendCancellableCoroutine { continuation -> val callback = object : Callback { override fun onResponse(call: Call, response: Response) { continuation.resume(response) { response.body?.close() } } override fun onFailure(call: Call, e: IOException) { // Don't bother with resuming the continuation if it is already cancelled. if (continuation.isCancelled) return val exception = IOException(e.message, e).apply { stackTrace = callStack } continuation.resumeWithException(exception) } } enqueue(callback) continuation.invokeOnCancellation { try { cancel() } catch (ex: Throwable) { // Ignore cancel exception } } } } suspend fun Call.await(): Response { val callStack = Exception().stackTrace.run { copyOfRange(1, size) } return await(callStack) } suspend fun Call.awaitSuccess(): Response { val callStack = Exception().stackTrace.run { copyOfRange(1, size) } val response = await(callStack) if (!response.isSuccessful) { response.close() throw HttpException(response.code).apply { stackTrace = callStack } } return response } class HttpException(code: Int) : IllegalStateException("HTTP error $code")