From d83e3eb10a7d013aa7695fd4c4694fdb2b076429 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Wed, 11 Nov 2020 11:15:19 +0600 Subject: [PATCH] add handling of 429 status --- .../Ktor/base/AbstractRequestCallFactory.kt | 21 +++++----- .../limiters/ExceptionsOnlyLimiter.kt | 38 ++++++++++++++----- 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/AbstractRequestCallFactory.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/AbstractRequestCallFactory.kt index 1abf10a653..11a25ddfac 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/AbstractRequestCallFactory.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/AbstractRequestCallFactory.kt @@ -1,5 +1,6 @@ package dev.inmo.tgbotapi.bot.Ktor.base +import dev.inmo.micro_utils.coroutines.safely import dev.inmo.tgbotapi.bot.Ktor.KtorCallFactory import dev.inmo.tgbotapi.bot.exceptions.newRequestException import dev.inmo.tgbotapi.requests.GetUpdates @@ -51,15 +52,17 @@ abstract class AbstractRequestCallFactory : KtorCallFactory { val content = response.receive() val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content) - return (responseObject.result?.let { - jsonFormatter.decodeFromJsonElement(request.resultDeserializer, it) - } ?: response.let { - throw newRequestException( - responseObject, - content, - "Can't get result object from $content" - ) - }) + return safely { + (responseObject.result?.let { + jsonFormatter.decodeFromJsonElement(request.resultDeserializer, it) + } ?: response.let { + throw newRequestException( + responseObject, + content, + "Can't get result object from $content" + ) + }) + } } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/settings/limiters/ExceptionsOnlyLimiter.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/settings/limiters/ExceptionsOnlyLimiter.kt index ca792b1575..e297ac9e2f 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/settings/limiters/ExceptionsOnlyLimiter.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/settings/limiters/ExceptionsOnlyLimiter.kt @@ -3,6 +3,8 @@ package dev.inmo.tgbotapi.bot.settings.limiters import dev.inmo.micro_utils.coroutines.safely import dev.inmo.tgbotapi.bot.exceptions.TooMuchRequestsException import dev.inmo.tgbotapi.types.RetryAfterError +import io.ktor.client.features.ClientRequestException +import io.ktor.http.HttpStatusCode import kotlinx.coroutines.delay import kotlinx.coroutines.flow.* @@ -16,18 +18,34 @@ object ExceptionsOnlyLimiter : RequestLimiter { while (true) { lockState.first { !it } val result = safely({ - if (it is TooMuchRequestsException) { - try { - safely { - lockState.emit(true) - delay(it.retryAfter.leftToRetry) + when (it) { + is TooMuchRequestsException -> { + try { + safely { + lockState.emit(true) + delay(it.retryAfter.leftToRetry) + } + } finally { + lockState.emit(false) } - } finally { - lockState.emit(false) + Result.failure(it) } - Result.failure(it) - } else { - throw it + is ClientRequestException -> { + if (it.response.status == HttpStatusCode.TooManyRequests) { + try { + safely { + lockState.emit(true) + delay(1000L) + } + } finally { + lockState.emit(false) + } + } else { + throw it + } + Result.failure(it) + } + else -> throw it } }) { Result.success(block())