OkHttp Call: split await() and awaitSuccess() (#8980)

(cherry picked from commit 448702e5beedcd0918c504da34a0feda20ee2817)
This commit is contained in:
stevenyomi 2023-01-25 11:34:31 +08:00 committed by Jobobby04
parent 1948545983
commit a0497d079d
30 changed files with 158 additions and 184 deletions

View File

@ -5,7 +5,7 @@ import androidx.core.net.toUri
import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.interceptor.rateLimit
import eu.kanade.tachiyomi.network.jsonMime
import eu.kanade.tachiyomi.network.parseAs
@ -59,7 +59,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
body = payload.toString().toRequestBody(jsonMime),
),
)
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let {
track.library_id =
@ -99,7 +99,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
}
}
authClient.newCall(POST(apiUrl, body = payload.toString().toRequestBody(jsonMime)))
.await()
.awaitSuccess()
track
}
}
@ -143,7 +143,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
body = payload.toString().toRequestBody(jsonMime),
),
)
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let { response ->
val data = response["data"]!!.jsonObject
@ -211,7 +211,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
body = payload.toString().toRequestBody(jsonMime),
),
)
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let { response ->
val data = response["data"]!!.jsonObject
@ -253,7 +253,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
body = payload.toString().toRequestBody(jsonMime),
),
)
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let {
val data = it["data"]!!.jsonObject

View File

@ -7,7 +7,7 @@ import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.lang.withIOContext
import kotlinx.serialization.decodeFromString
@ -40,7 +40,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
.add("status", track.toBangumiStatus())
.build()
authClient.newCall(POST("$apiUrl/collection/${track.media_id}/update", body = body))
.await()
.awaitSuccess()
track
}
}
@ -53,7 +53,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
.add("status", track.toBangumiStatus())
.build()
authClient.newCall(POST("$apiUrl/collection/${track.media_id}/update", body = sbody))
.await()
.awaitSuccess()
// chapter update
val body = FormBody.Builder()
@ -64,7 +64,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
"$apiUrl/subject/${track.media_id}/update/watched_eps",
body = body,
),
).await()
).awaitSuccess()
track
}
@ -78,7 +78,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
.appendQueryParameter("max_results", "20")
.build()
authClient.newCall(GET(url.toString()))
.await()
.awaitSuccess()
.use {
var responseBody = it.body.string()
if (responseBody.isEmpty()) {
@ -119,7 +119,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
suspend fun findLibManga(track: Track): Track? {
return withIOContext {
authClient.newCall(GET("$apiUrl/subject/${track.media_id}"))
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let { jsonToSearch(it) }
}
@ -135,7 +135,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
.build()
// TODO: get user readed chapter here
val response = authClient.newCall(requestUserRead).await()
val response = authClient.newCall(requestUserRead).awaitSuccess()
val responseBody = response.body.string()
if (responseBody.isEmpty()) {
throw Exception("Null Response")
@ -156,7 +156,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
suspend fun accessToken(code: String): OAuth {
return withIOContext {
client.newCall(accessTokenRequest(code))
.await()
.awaitSuccess()
.parseAs()
}
}

View File

@ -4,7 +4,7 @@ import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.system.logcat
@ -128,7 +128,7 @@ class KavitaApi(private val client: OkHttpClient, interceptor: KavitaInterceptor
suspend fun getTrackSearch(url: String): TrackSearch = withIOContext {
try {
val serieDto: SeriesDto = authClient.newCall(GET(url))
.await()
.awaitSuccess()
.parseAs()
val track = serieDto.toTrack()
@ -154,7 +154,7 @@ class KavitaApi(private val client: OkHttpClient, interceptor: KavitaInterceptor
suspend fun updateProgress(track: Track): Track {
val requestUrl = "${getApiFromUrl(track.tracking_url)}/Tachiyomi/mark-chapter-until-as-read?seriesId=${getIdFromUrl(track.tracking_url)}&chapterNumber=${track.last_chapter_read}"
authClient.newCall(POST(requestUrl, body = "{}".toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())))
.await()
.awaitSuccess()
return getTrackSearch(track.tracking_url)
}
}

View File

@ -5,7 +5,7 @@ import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.jsonMime
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.lang.withIOContext
@ -67,7 +67,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
body = data.toString().toRequestBody("application/vnd.api+json".toMediaType()),
),
)
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let {
track.media_id = it["data"]!!.jsonObject["id"]!!.jsonPrimitive.long
@ -104,7 +104,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
.patch(data.toString().toRequestBody("application/vnd.api+json".toMediaType()))
.build(),
)
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let {
track
@ -115,7 +115,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
suspend fun search(query: String): List<TrackSearch> {
return withIOContext {
authClient.newCall(GET(algoliaKeyUrl))
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let {
val key = it["media"]!!.jsonObject["key"]!!.jsonPrimitive.content
@ -142,7 +142,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
body = jsonObject.toString().toRequestBody(jsonMime),
),
)
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let {
it["hits"]!!.jsonArray
@ -160,7 +160,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
.appendQueryParameter("include", "manga")
.build()
authClient.newCall(GET(url.toString()))
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let {
val data = it["data"]!!.jsonArray
@ -181,7 +181,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
.appendQueryParameter("include", "manga")
.build()
authClient.newCall(GET(url.toString()))
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let {
val data = it["data"]!!.jsonArray
@ -205,7 +205,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
.add("client_secret", clientSecret)
.build()
client.newCall(POST(loginUrl, body = formBody))
.await()
.awaitSuccess()
.parseAs()
}
}
@ -216,7 +216,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
.encodedQuery("filter[self]=true")
.build()
authClient.newCall(GET(url.toString()))
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let {
it["data"]!!.jsonArray[0].jsonObject["id"]!!.jsonPrimitive.content

View File

@ -4,7 +4,7 @@ import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.system.logcat
@ -28,19 +28,19 @@ class KomgaApi(private val client: OkHttpClient) {
try {
val track = if (url.contains(READLIST_API)) {
client.newCall(GET(url))
.await()
.awaitSuccess()
.parseAs<ReadListDto>()
.toTrack()
} else {
client.newCall(GET(url))
.await()
.awaitSuccess()
.parseAs<SeriesDto>()
.toTrack()
}
val progress = client
.newCall(GET("${url.replace("/api/v1/series/", "/api/v2/series/")}/read-progress/tachiyomi"))
.await().let {
.awaitSuccess().let {
if (url.contains("/api/v1/series/")) {
it.parseAs<ReadProgressV2Dto>()
} else {
@ -77,7 +77,7 @@ class KomgaApi(private val client: OkHttpClient) {
.put(payload.toRequestBody("application/json".toMediaType()))
.build(),
)
.await()
.awaitSuccess()
return getTrackSearch(track.tracking_url)
}

View File

@ -11,7 +11,7 @@ import eu.kanade.tachiyomi.network.DELETE
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.PUT
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.serialization.json.Json
@ -53,7 +53,7 @@ class MangaUpdatesApi(
url = "$baseUrl/v1/lists/series/${track.media_id}",
),
)
.await()
.awaitSuccess()
.parseAs<ListItem>()
val rating = getSeriesRating(track)
@ -77,7 +77,7 @@ class MangaUpdatesApi(
body = body.toString().toRequestBody(contentType),
),
)
.await()
.awaitSuccess()
.let {
if (it.code == 200) {
track.status = status
@ -104,7 +104,7 @@ class MangaUpdatesApi(
body = body.toString().toRequestBody(contentType),
),
)
.await()
.awaitSuccess()
updateSeriesRating(track)
}
@ -116,7 +116,7 @@ class MangaUpdatesApi(
url = "$baseUrl/v1/series/${track.media_id}/rating",
),
)
.await()
.awaitSuccess()
.parseAs<Rating>()
} catch (e: Exception) {
null
@ -134,14 +134,14 @@ class MangaUpdatesApi(
body = body.toString().toRequestBody(contentType),
),
)
.await()
.awaitSuccess()
} else {
authClient.newCall(
DELETE(
url = "$baseUrl/v1/series/${track.media_id}/rating",
),
)
.await()
.awaitSuccess()
}
}
@ -162,7 +162,7 @@ class MangaUpdatesApi(
body = body.toString().toRequestBody(contentType),
),
)
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let { obj ->
obj["results"]?.jsonArray?.map { element ->
@ -183,7 +183,7 @@ class MangaUpdatesApi(
body = body.toString().toRequestBody(contentType),
),
)
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let { obj ->
try {

View File

@ -7,7 +7,7 @@ import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.PkceUtil
import eu.kanade.tachiyomi.util.lang.withIOContext
@ -43,7 +43,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.add("grant_type", "authorization_code")
.build()
client.newCall(POST("$baseOAuthUrl/token", body = formBody))
.await()
.awaitSuccess()
.parseAs()
}
}
@ -55,7 +55,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.get()
.build()
authClient.newCall(request)
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let { it["name"]!!.jsonPrimitive.content }
}
@ -69,7 +69,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.appendQueryParameter("nsfw", "true")
.build()
authClient.newCall(GET(url.toString()))
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let {
it["data"]!!.jsonArray
@ -91,7 +91,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.appendQueryParameter("fields", "id,title,synopsis,num_chapters,main_picture,status,media_type,start_date")
.build()
authClient.newCall(GET(url.toString()))
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let {
val obj = it.jsonObject
@ -134,7 +134,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.put(formBodyBuilder.build())
.build()
authClient.newCall(request)
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let { parseMangaItem(it, track) }
}
@ -147,7 +147,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.appendQueryParameter("fields", "num_chapters,my_list_status{start_date,finish_date}")
.build()
authClient.newCall(GET(uri.toString()))
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let { obj ->
track.total_chapters = obj["num_chapters"]!!.jsonPrimitive.int
@ -199,7 +199,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.get()
.build()
authClient.newCall(request)
.await()
.awaitSuccess()
.parseAs()
}
}

View File

@ -6,7 +6,7 @@ import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.jsonMime
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.lang.withIOContext
@ -46,7 +46,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
"$apiUrl/v2/user_rates",
body = payload.toString().toRequestBody(jsonMime),
),
).await()
).awaitSuccess()
track
}
}
@ -61,7 +61,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
.appendQueryParameter("limit", "20")
.build()
authClient.newCall(GET(url.toString()))
.await()
.awaitSuccess()
.parseAs<JsonArray>()
.let { response ->
response.map {
@ -103,7 +103,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
.appendPath(track.media_id.toString())
.build()
val mangas = authClient.newCall(GET(urlMangas.toString()))
.await()
.awaitSuccess()
.parseAs<JsonObject>()
val url = "$apiUrl/v2/user_rates".toUri().buildUpon()
@ -112,7 +112,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
.appendQueryParameter("target_type", "Manga")
.build()
authClient.newCall(GET(url.toString()))
.await()
.awaitSuccess()
.parseAs<JsonArray>()
.let { response ->
if (response.size > 1) {
@ -128,7 +128,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
suspend fun getCurrentUser(): Int {
return authClient.newCall(GET("$apiUrl/users/whoami"))
.await()
.awaitSuccess()
.parseAs<JsonObject>()
.let {
it["id"]!!.jsonPrimitive.int
@ -138,7 +138,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
suspend fun accessToken(code: String): OAuth {
return withIOContext {
client.newCall(accessTokenRequest(code))
.await()
.awaitSuccess()
.parseAs()
}
}

View File

@ -8,7 +8,7 @@ import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.PUT
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.lang.withIOContext
import okhttp3.Credentials
@ -50,7 +50,7 @@ class TachideskApi {
trackUrl
}
val manga = client.newCall(GET("$url/full", headers)).await().parseAs<MangaDataClass>()
val manga = client.newCall(GET("$url/full", headers)).awaitSuccess().parseAs<MangaDataClass>()
TrackSearch.create(TrackManager.SUWAYOMI).apply {
title = manga.title
@ -70,7 +70,7 @@ class TachideskApi {
suspend fun updateProgress(track: Track): Track {
val url = track.tracking_url
val chapters = client.newCall(GET("$url/chapters", headers)).await().parseAs<List<ChapterDataClass>>()
val chapters = client.newCall(GET("$url/chapters", headers)).awaitSuccess().parseAs<List<ChapterDataClass>>()
val lastChapterIndex = chapters.first { it.chapterNumber == track.last_chapter_read }.index
client.newCall(
@ -82,7 +82,7 @@ class TachideskApi {
.add("read", "true")
.build(),
),
).await()
).awaitSuccess()
return getTrackSearch(track.tracking_url)
}

View File

@ -6,7 +6,7 @@ import eu.kanade.tachiyomi.core.preference.Preference
import eu.kanade.tachiyomi.core.preference.PreferenceStore
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.system.isInstalledFromFDroid
@ -34,7 +34,7 @@ class AppUpdateChecker {
return withIOContext {
val result = networkService.client
.newCall(GET("https://api.github.com/repos/$GITHUB_REPO/releases/latest"))
.await()
.awaitSuccess()
.parseAs<GithubRelease>()
.let {
lastAppCheck.set(Date().time)

View File

@ -12,7 +12,7 @@ import eu.kanade.tachiyomi.extension.model.LoadResult
import eu.kanade.tachiyomi.extension.util.ExtensionLoader
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.system.logcat
@ -47,7 +47,7 @@ internal class ExtensionGithubApi {
try {
networkService.client
.newCall(GET("${REPO_URL_PREFIX}index.min.json"))
.await()
.awaitSuccess()
} catch (e: Throwable) {
logcat(LogPriority.ERROR, e) { "Failed to get extensions from GitHub" }
requiresFallbackSource = true
@ -58,7 +58,7 @@ internal class ExtensionGithubApi {
val response = githubResponse ?: run {
networkService.client
.newCall(GET("${FALLBACK_REPO_URL_PREFIX}index.min.json"))
.await()
.awaitSuccess()
}
val extensions = response
@ -73,7 +73,7 @@ internal class ExtensionGithubApi {
}
networkService.client
.newCall(GET("${url}index.min.json"))
.await()
.awaitSuccess()
.parseAs<List<ExtensionJsonObject>>()
.toExtensions(url, repoSource = true)
}

View File

@ -9,6 +9,7 @@ import eu.kanade.domain.UnsortedPreferences
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.newCachelessCallWithProgress
import eu.kanade.tachiyomi.source.PagePreviewInfo
import eu.kanade.tachiyomi.source.PagePreviewPage
@ -50,7 +51,6 @@ import exh.ui.login.EhLoginActivity
import exh.util.UriFilter
import exh.util.UriGroup
import exh.util.asObservableWithAsyncStacktrace
import exh.util.awaitResponse
import exh.util.dropBlank
import exh.util.ignore
import exh.util.nullIfBlank
@ -339,7 +339,7 @@ class EHentai(
)
if (cachedParent == null) {
throttleFunc()
doc = client.newCall(exGet(baseUrl + url)).await().asJsoup()
doc = client.newCall(exGet(baseUrl + url)).awaitSuccess().asJsoup()
val parentLink = doc.select("#gdd .gdt1").find { el ->
el.text().lowercase() == "parent:"
@ -612,7 +612,7 @@ class EHentai(
override suspend fun getMangaDetails(manga: SManga): SManga {
val exception = Exception("Async stacktrace")
val response = client.newCall(mangaDetailsRequest(manga)).awaitResponse()
val response = client.newCall(mangaDetailsRequest(manga)).await()
if (response.isSuccessful) {
// Pull to most recent
val doc = response.asJsoup()
@ -621,7 +621,7 @@ class EHentai(
val sManga = manga.copy(
url = EHentaiSearchMetadata.normalizeUrl(newerGallery.attr("href")),
)
client.newCall(mangaDetailsRequest(sManga)).await().asJsoup()
client.newCall(mangaDetailsRequest(sManga)).awaitSuccess().asJsoup()
} else {
doc
}
@ -790,7 +790,7 @@ class EHentai(
next = page,
cacheControl = CacheControl.FORCE_NETWORK,
),
).awaitResponse()
).await()
}
val doc = response2.asJsoup()
@ -1142,7 +1142,7 @@ class EHentai(
.build()
.toString(),
),
).await().asJsoup()
).awaitSuccess().asJsoup()
val previews = if (doc.selectFirst("div#gdo4 .ths")!!.attr("onClick").contains("inline_set=ts_l")) {
doc.body()
.select("#gdt div a")
@ -1169,7 +1169,7 @@ class EHentai(
}
override suspend fun fetchPreviewImage(page: PagePreviewInfo, cacheControl: CacheControl?): Response {
return client.newCachelessCallWithProgress(exGet(page.imageUrl, cacheControl = cacheControl), page).await()
return client.newCachelessCallWithProgress(exGet(page.imageUrl, cacheControl = cacheControl), page).awaitSuccess()
}
/**

View File

@ -4,7 +4,7 @@ import android.content.Context
import android.content.SharedPreferences
import android.net.Uri
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.newCachelessCallWithProgress
import eu.kanade.tachiyomi.source.PagePreviewInfo
import eu.kanade.tachiyomi.source.PagePreviewPage
@ -55,7 +55,7 @@ class NHentai(delegate: HttpSource, val context: Context) :
}
override suspend fun getMangaDetails(manga: SManga): SManga {
val response = client.newCall(mangaDetailsRequest(manga)).await()
val response = client.newCall(mangaDetailsRequest(manga)).awaitSuccess()
return parseToManga(manga, response)
}
@ -175,7 +175,7 @@ class NHentai(delegate: HttpSource, val context: Context) :
override suspend fun getPagePreviewList(manga: SManga, chapters: List<SChapter>, page: Int): PagePreviewPage {
val metadata = fetchOrLoadMetadata(manga.id()) {
client.newCall(mangaDetailsRequest(manga)).await()
client.newCall(mangaDetailsRequest(manga)).awaitSuccess()
}
return PagePreviewPage(
page,
@ -199,7 +199,7 @@ class NHentai(delegate: HttpSource, val context: Context) :
GET(page.imageUrl)
},
page,
).await()
).awaitSuccess()
}
companion object {

View File

@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.source.online.english
import android.content.Context
import android.net.Uri
import androidx.core.net.toUri
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource
@ -33,7 +33,7 @@ class EightMuses(delegate: HttpSource, val context: Context) :
}
override suspend fun getMangaDetails(manga: SManga): SManga {
val response = client.newCall(mangaDetailsRequest(manga)).await()
val response = client.newCall(mangaDetailsRequest(manga)).awaitSuccess()
return parseToManga(manga, response.asJsoup())
}

View File

@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.source.online.english
import android.content.Context
import android.net.Uri
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource
@ -32,7 +32,7 @@ class HBrowse(delegate: HttpSource, val context: Context) :
}
override suspend fun getMangaDetails(manga: SManga): SManga {
val response = client.newCall(mangaDetailsRequest(manga)).await()
val response = client.newCall(mangaDetailsRequest(manga)).awaitSuccess()
return parseToManga(manga, response.asJsoup())
}

View File

@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.source.online.english
import android.content.Context
import android.net.Uri
import androidx.core.net.toUri
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SManga
@ -52,7 +52,7 @@ class Pururin(delegate: HttpSource, val context: Context) :
}
override suspend fun getMangaDetails(manga: SManga): SManga {
val response = client.newCall(mangaDetailsRequest(manga)).await()
val response = client.newCall(mangaDetailsRequest(manga)).awaitSuccess()
return parseToManga(manga, response.asJsoup())
}

View File

@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.source.online.english
import android.content.Context
import android.net.Uri
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SManga
@ -47,7 +47,7 @@ class Tsumino(delegate: HttpSource, val context: Context) :
}
override suspend fun getMangaDetails(manga: SManga): SManga {
val response = client.newCall(mangaDetailsRequest(manga)).await()
val response = client.newCall(mangaDetailsRequest(manga)).awaitSuccess()
return parseToManga(manga, response.asJsoup())
}

View File

@ -1,7 +1,7 @@
package exh.md.handlers
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.source.model.Page
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonArray
@ -24,7 +24,7 @@ class AzukiHandler(currentClient: OkHttpClient, userAgent: String) {
suspend fun fetchPageList(externalUrl: String): List<Page> {
val chapterId = externalUrl.substringAfterLast("/").substringBefore("?")
val request = pageListRequest(chapterId)
return pageListParse(client.newCall(request).await())
return pageListParse(client.newCall(request).awaitSuccess())
}
private fun pageListRequest(chapterId: String): Request {

View File

@ -2,7 +2,7 @@ package exh.md.handlers
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.interceptor.rateLimit
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.source.model.Page
@ -92,7 +92,7 @@ class BilibiliHandler(currentClient: OkHttpClient) {
}
suspend fun getChapterList(mangaUrl: String): List<SChapter> {
val response = client.newCall(mangaDetailsApiRequest(mangaUrl)).await()
val response = client.newCall(mangaDetailsApiRequest(mangaUrl)).awaitSuccess()
return chapterListParse(response)
}
@ -115,7 +115,7 @@ class BilibiliHandler(currentClient: OkHttpClient) {
)
private suspend fun fetchPageList(chapterUrl: String): List<Page> {
val response = client.newCall(pageListRequest(chapterUrl)).await()
val response = client.newCall(pageListRequest(chapterUrl)).awaitSuccess()
return pageListParse(response)
}

View File

@ -1,7 +1,7 @@
package exh.md.handlers
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.util.asJsoup
import kotlinx.serialization.json.Json
@ -29,13 +29,13 @@ class ComikeyHandler(cloudflareClient: OkHttpClient, userAgent: String) {
suspend fun fetchPageList(externalUrl: String): List<Page> {
val httpUrl = externalUrl.toHttpUrl()
val mangaId = getMangaId(httpUrl.pathSegments[1])
val response = client.newCall(pageListRequest(mangaId, httpUrl.pathSegments[2])).await()
val response = client.newCall(pageListRequest(mangaId, httpUrl.pathSegments[2])).awaitSuccess()
val request = getActualPageList(response) ?: return listOf(Page(0, urlForbidden, urlForbidden))
return pageListParse(client.newCall(request).await())
return pageListParse(client.newCall(request).awaitSuccess())
}
suspend fun getMangaId(mangaUrl: String): Int {
val response = client.newCall(GET("$baseUrl/read/$mangaUrl")).await()
val response = client.newCall(GET("$baseUrl/read/$mangaUrl")).awaitSuccess()
val url = response.asJsoup().selectFirst("meta[property=og:url]")!!.attr("content")
return url.trimEnd('/').substringAfterLast('/').toInt()
}

View File

@ -1,7 +1,7 @@
package exh.md.handlers
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.source.model.Page
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonArray
@ -22,7 +22,7 @@ class MangaHotHandler(currentClient: OkHttpClient, userAgent: String) {
suspend fun fetchPageList(externalUrl: String): List<Page> {
val request = GET(externalUrl.substringBefore("?").replace(baseUrl, apiUrl).replace("viewer", "v1/works/storyDetail"), headers)
return pageListParse(client.newCall(request).await())
return pageListParse(client.newCall(request).awaitSuccess())
}
fun pageListParse(response: Response): List<Page> {

View File

@ -1,7 +1,7 @@
package exh.md.handlers
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.source.model.Page
import exh.md.dto.MangaPlusResponse
import kotlinx.serialization.decodeFromByteArray
@ -28,7 +28,7 @@ class MangaPlusHandler(currentClient: OkHttpClient) {
.build()
suspend fun fetchPageList(chapterId: String): List<Page> {
val response = client.newCall(pageListRequest(chapterId.substringAfterLast("/"))).await()
val response = client.newCall(pageListRequest(chapterId.substringAfterLast("/"))).awaitSuccess()
return pageListParse(response)
}

View File

@ -4,7 +4,7 @@ import eu.kanade.domain.track.service.TrackPreferences
import eu.kanade.tachiyomi.data.track.mdlist.MdList
import eu.kanade.tachiyomi.data.track.myanimelist.OAuth
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.system.logcat
import exh.md.utils.MdApi
@ -35,7 +35,7 @@ class MangaDexLoginHelper(
.build()
val error = kotlin.runCatching {
val data = client.newCall(POST(MdApi.baseAuthUrl + MdApi.token, body = loginFormBody)).await().parseAs<OAuth>()
val data = client.newCall(POST(MdApi.baseAuthUrl + MdApi.token, body = loginFormBody)).awaitSuccess().parseAs<OAuth>()
mangaDexAuthInterceptor.setAuth(data)
}.exceptionOrNull()
@ -72,7 +72,7 @@ class MangaDexLoginHelper(
.build(),
body = formBody,
),
).await()
).awaitSuccess()
mdList.logout()
}.exceptionOrNull()

View File

@ -2,7 +2,7 @@ package exh.md.service
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs
import exh.md.dto.MangaListDto
import exh.md.dto.RatingDto
@ -32,7 +32,7 @@ class MangaDexAuthService(
headers,
CacheControl.FORCE_NETWORK,
),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
suspend fun readingStatusForManga(mangaId: String): ReadingStatusDto {
@ -42,7 +42,7 @@ class MangaDexAuthService(
headers,
CacheControl.FORCE_NETWORK,
),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
suspend fun readChaptersForManga(mangaId: String): ReadChapterDto {
@ -52,7 +52,7 @@ class MangaDexAuthService(
headers,
CacheControl.FORCE_NETWORK,
),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
suspend fun updateReadingStatusForManga(
@ -66,7 +66,7 @@ class MangaDexAuthService(
body = MdUtil.encodeToBody(readingStatusDto),
cache = CacheControl.FORCE_NETWORK,
),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
suspend fun readingStatusAllManga(): ReadingStatusMapDto {
@ -76,7 +76,7 @@ class MangaDexAuthService(
headers,
cache = CacheControl.FORCE_NETWORK,
),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
suspend fun readingStatusByType(status: String): ReadingStatusMapDto {
@ -86,7 +86,7 @@ class MangaDexAuthService(
headers,
cache = CacheControl.FORCE_NETWORK,
),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
suspend fun markChapterRead(chapterId: String): ResultDto {
@ -96,7 +96,7 @@ class MangaDexAuthService(
headers,
cache = CacheControl.FORCE_NETWORK,
),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
suspend fun markChapterUnRead(chapterId: String): ResultDto {
@ -107,7 +107,7 @@ class MangaDexAuthService(
.headers(headers)
.cacheControl(CacheControl.FORCE_NETWORK)
.build(),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
suspend fun followManga(mangaId: String): ResultDto {
@ -117,7 +117,7 @@ class MangaDexAuthService(
headers,
cache = CacheControl.FORCE_NETWORK,
),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
suspend fun unfollowManga(mangaId: String): ResultDto {
@ -128,7 +128,7 @@ class MangaDexAuthService(
.headers(headers)
.cacheControl(CacheControl.FORCE_NETWORK)
.build(),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
suspend fun updateMangaRating(mangaId: String, rating: Int): ResultDto {
@ -139,7 +139,7 @@ class MangaDexAuthService(
body = MdUtil.encodeToBody(RatingDto(rating)),
cache = CacheControl.FORCE_NETWORK,
),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
suspend fun deleteMangaRating(mangaId: String): ResultDto {
@ -150,7 +150,7 @@ class MangaDexAuthService(
.headers(headers)
.cacheControl(CacheControl.FORCE_NETWORK)
.build(),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
suspend fun mangasRating(vararg mangaIds: String): RatingResponseDto {
@ -167,6 +167,6 @@ class MangaDexAuthService(
headers,
cache = CacheControl.FORCE_NETWORK,
),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
}

View File

@ -2,7 +2,7 @@ package exh.md.service
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs
import exh.md.dto.AggregateDto
import exh.md.dto.AtHomeDto
@ -45,7 +45,7 @@ class MangaDexService(
.build(),
cache = CacheControl.FORCE_NETWORK,
),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
suspend fun viewManga(
@ -64,7 +64,7 @@ class MangaDexService(
.build(),
cache = CacheControl.FORCE_NETWORK,
),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
suspend fun mangasRating(
@ -82,7 +82,7 @@ class MangaDexService(
.build(),
cache = CacheControl.FORCE_NETWORK,
),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
suspend fun aggregateChapters(
@ -101,7 +101,7 @@ class MangaDexService(
.build(),
cache = CacheControl.FORCE_NETWORK,
),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
private fun String.splitString() = replace("\n", "").split(',').trimAll().dropEmpty()
@ -142,18 +142,18 @@ class MangaDexService(
url,
cache = CacheControl.FORCE_NETWORK,
),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
suspend fun viewChapter(id: String): ChapterDto {
return client.newCall(GET("${MdApi.chapter}/$id", cache = CacheControl.FORCE_NETWORK))
.await()
.awaitSuccess()
.parseAs(MdUtil.jsonParser)
}
suspend fun randomManga(): MangaDto {
return client.newCall(GET("${MdApi.manga}/random", cache = CacheControl.FORCE_NETWORK))
.await()
.awaitSuccess()
.parseAs(MdUtil.jsonParser)
}
@ -164,7 +164,7 @@ class MangaDexService(
body = MdUtil.encodeToBody(atHomeImageReportDto),
cache = CacheControl.FORCE_NETWORK,
),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
suspend fun getAtHomeServer(
@ -172,7 +172,7 @@ class MangaDexService(
headers: Headers,
): AtHomeDto {
return client.newCall(GET(atHomeRequestUrl, headers, CacheControl.FORCE_NETWORK))
.await()
.awaitSuccess()
.parseAs(MdUtil.jsonParser)
}
@ -187,6 +187,6 @@ class MangaDexService(
.build(),
cache = CacheControl.FORCE_NETWORK,
),
).await().parseAs(MdUtil.jsonParser)
).awaitSuccess().parseAs(MdUtil.jsonParser)
}
}

View File

@ -1,7 +1,7 @@
package exh.md.service
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs
import exh.md.dto.SimilarMangaDto
import exh.md.utils.MdUtil
@ -15,6 +15,6 @@ class SimilarService(
GET(
"${MdUtil.similarBaseApi}$mangaId.json",
),
).await().parseAs()
).awaitSuccess().parseAs()
}
}

View File

@ -7,7 +7,7 @@ import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.model.MangasPage
@ -52,7 +52,7 @@ class MyAnimeList : API("https://api.jikan.moe/v4/") {
.addPathSegment("recommendations")
.build()
val data = client.newCall(GET(apiUrl)).await().parseAs<JsonObject>()
val data = client.newCall(GET(apiUrl)).awaitSuccess().parseAs<JsonObject>()
return data["data"]!!.jsonArray
.map { it.jsonObject["entry"]!!.jsonObject }
.map { rec ->
@ -88,7 +88,7 @@ class MyAnimeList : API("https://api.jikan.moe/v4/") {
.addQueryParameter("q", search)
.build()
val data = client.newCall(GET(url)).await()
val data = client.newCall(GET(url)).awaitSuccess()
.parseAs<JsonObject>()
return getRecsById(data["data"]!!.jsonArray.first().jsonObject["mal_id"]!!.jsonPrimitive.content)
}
@ -137,7 +137,7 @@ class Anilist : API("https://graphql.anilist.co/") {
}
val payloadBody = payload.toString().toRequestBody("application/json; charset=utf-8".toMediaType())
val data = client.newCall(POST(endpoint, body = payloadBody)).await()
val data = client.newCall(POST(endpoint, body = payloadBody)).awaitSuccess()
.parseAs<JsonObject>()
val media = data["data"]!!

View File

@ -3,7 +3,7 @@ package exh.uconfig
import android.content.Context
import eu.kanade.domain.UnsortedPreferences
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.all.EHentai
import eu.kanade.tachiyomi.util.asJsoup
@ -46,7 +46,7 @@ class EHConfigurator(val context: Context) {
)
.build(),
)
.await()
.awaitSuccess()
private val EHentai.uconfigUrl get() = baseUrl + UCONFIG_URL
@ -60,7 +60,7 @@ class EHConfigurator(val context: Context) {
.url(HATH_PERKS_URL)
.build(),
)
.await().asJsoup()
.awaitSuccess().asJsoup()
val hathPerks = EHHathPerksResponse()
@ -90,7 +90,7 @@ class EHConfigurator(val context: Context) {
private suspend fun configure(source: EHentai, hathPerks: EHHathPerksResponse) {
// Delete old app profiles
val scanReq = source.requestWithCreds().url(source.uconfigUrl).build()
val resp = configuratorClient.newCall(scanReq).await().asJsoup()
val resp = configuratorClient.newCall(scanReq).awaitSuccess().asJsoup()
var lastDoc = resp
resp.select(PROFILE_SELECTOR).forEach {
if (it.text() == PROFILE_NAME) {
@ -129,7 +129,7 @@ class EHConfigurator(val context: Context) {
.url(source.uconfigUrl)
.post(form)
.build(),
).await()
).awaitSuccess()
// Persist slot + sk
source.spPref().set(slot)

View File

@ -1,17 +1,11 @@
package exh.util
import kotlinx.coroutines.suspendCancellableCoroutine
import okhttp3.Call
import okhttp3.Callback
import okhttp3.Response
import okhttp3.internal.closeQuietly
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<Pair<Exception, Response>> {
// Record stacktrace at creation time for easier debugging
@ -58,34 +52,3 @@ fun Call.asObservableWithAsyncStacktrace(): Observable<Pair<Exception, Response>
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) {
response.closeQuietly()
}
}
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
}
}
}
}

View File

@ -65,16 +65,11 @@ fun Call.asObservable(): Observable<Response> {
// Based on https://github.com/gildor/kotlin-coroutines-okhttp
@OptIn(ExperimentalCoroutinesApi::class)
suspend fun Call.await(): Response {
private suspend fun Call.await(callStack: Array<StackTraceElement>): Response {
return suspendCancellableCoroutine { continuation ->
enqueue(
val callback =
object : Callback {
override fun onResponse(call: Call, response: Response) {
if (!response.isSuccessful) {
continuation.resumeWithException(HttpException(response.code))
return
}
continuation.resume(response) {
response.body.close()
}
@ -83,11 +78,12 @@ suspend fun Call.await(): 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)
val exception = IOException(e).apply { stackTrace = callStack }
continuation.resumeWithException(exception)
}
},
)
}
enqueue(callback)
continuation.invokeOnCancellation {
try {
@ -99,6 +95,21 @@ suspend fun Call.await(): Response {
}
}
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
}
fun Call.asObservableSuccess(): Observable<Response> {
return asObservable().doOnNext { response ->
if (!response.isSuccessful) {