mirror of
https://github.com/IllusionMan1212/lyrics-grabbr.git
synced 2026-10-24 02:12:27 +00:00
58 lines
1.9 KiB
Kotlin
58 lines
1.9 KiB
Kotlin
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<StackTraceElement>): 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") |