From 4500711db42c388199e6f9499d5075cb4bad50cd Mon Sep 17 00:00:00 2001 From: emad Date: Sun, 19 Apr 2026 03:24:16 +0300 Subject: [PATCH] Detect Too Many Requests descriptions case-insensitively Telegram has been observed to return both "Bad Request: Too Many Requests: retry after N" and "Bad Request: too Many Requests: retry after N" (lowercase leading 't'). The current case-sensitive check silently misses the latter and the caller never sees a TooMuchRequestsException. Added `ignoreCase = true` to the contains(...) check and three regression tests covering canonical, lowercase-initial, and all-lowercase casings. Closes #1008 --- .../bot/exceptions/RequestException.kt | 2 +- .../exceptions/NewRequestExceptionTests.kt | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/bot/exceptions/NewRequestExceptionTests.kt diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/exceptions/RequestException.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/exceptions/RequestException.kt index bce5c8b3e6..43dd097740 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/exceptions/RequestException.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/exceptions/RequestException.kt @@ -22,7 +22,7 @@ fun newRequestException( description == "Unauthorized" -> UnauthorizedException(response, plainAnswer, message, cause) description.contains("PHOTO_INVALID_DIMENSIONS") -> InvalidPhotoDimensionsException(response, plainAnswer, message, cause) description.contains("wrong file identifier") -> WrongFileIdentifierException(response, plainAnswer, message, cause) - description.contains("Too Many Requests") -> TooMuchRequestsException( + description.contains("Too Many Requests", ignoreCase = true) -> TooMuchRequestsException( (response.parameters ?.error as? RetryAfterError) ?: RetryAfterError(60, DateTime.now().unixMillisLong), response, plainAnswer, diff --git a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/bot/exceptions/NewRequestExceptionTests.kt b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/bot/exceptions/NewRequestExceptionTests.kt new file mode 100644 index 0000000000..bae9e8d0bd --- /dev/null +++ b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/bot/exceptions/NewRequestExceptionTests.kt @@ -0,0 +1,39 @@ +package dev.inmo.tgbotapi.bot.exceptions + +import dev.inmo.tgbotapi.types.Response +import kotlin.test.Test +import kotlin.test.assertIs + +/** + * Regression tests for https://github.com/InsanusMokrassar/TelegramBotAPI/issues/1008 — + * Telegram's "Too Many Requests" response is case-inconsistent (both + * `Too Many Requests` and `too Many Requests` have been observed), so the + * description match must be case-insensitive. + */ +class NewRequestExceptionTests { + private fun buildException(description: String) = newRequestException( + response = Response(ok = false, description = description, errorCode = 429), + plainAnswer = "{\"ok\":false}" + ) + + @Test + fun `TooMuchRequestsException is created for canonical casing`() { + assertIs( + buildException("Bad Request: Too Many Requests: retry after 8") + ) + } + + @Test + fun `TooMuchRequestsException is created for lowercase first-letter casing`() { + assertIs( + buildException("Bad Request: too Many Requests: retry after 8") + ) + } + + @Test + fun `TooMuchRequestsException is created for all-lowercase casing`() { + assertIs( + buildException("Bad Request: too many requests: retry after 8") + ) + } +}