Improve support of new exceptions recovering mechanism

This commit is contained in:
InsanusMokrassar 2022-09-19 01:39:23 +06:00
parent 6004b159ec
commit c1374c118d
4 changed files with 56 additions and 31 deletions

View File

@ -2,6 +2,9 @@
## 3.2.5 ## 3.2.5
* `Common`:
* Improve support of new exceptions recovering mechanism
## 3.2.4 ## 3.2.4
* `API`: * `API`:

View File

@ -4,6 +4,7 @@ import com.soywiz.klock.DateTime
import dev.inmo.tgbotapi.types.Response import dev.inmo.tgbotapi.types.Response
import dev.inmo.tgbotapi.types.RetryAfterError import dev.inmo.tgbotapi.types.RetryAfterError
import io.ktor.utils.io.errors.IOException import io.ktor.utils.io.errors.IOException
import kotlinx.coroutines.CopyableThrowable
fun newRequestException( fun newRequestException(
response: Response, response: Response,
@ -35,9 +36,11 @@ fun newRequestException(
} }
} ?: CommonRequestException(response, plainAnswer, message, cause) } ?: CommonRequestException(response, plainAnswer, message, cause)
sealed class BotException(message: String = "Something went wrong", cause: Throwable? = null) : IOException(message, cause) sealed class BotException(message: String = "Something went wrong", cause: Throwable? = null) : IOException(message, cause), CopyableThrowable<BotException>
class CommonBotException(message: String = "Something went wrong", cause: Throwable? = null) : BotException(message, cause) class CommonBotException(message: String = "Something went wrong", cause: Throwable? = null) : BotException(message, cause) {
override fun createCopy(): BotException = CommonBotException(message!!, cause)
}
sealed class RequestException constructor( sealed class RequestException constructor(
val response: Response, val response: Response,
@ -50,28 +53,46 @@ sealed class RequestException constructor(
) )
class CommonRequestException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) : class CommonRequestException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
RequestException(response, plainAnswer, message, cause) RequestException(response, plainAnswer, message, cause) {
override fun createCopy(): BotException = CommonRequestException(response, plainAnswer, message, cause)
}
class UnauthorizedException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) : class UnauthorizedException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
RequestException(response, plainAnswer, message, cause) RequestException(response, plainAnswer, message, cause) {
override fun createCopy(): BotException = UnauthorizedException(response, plainAnswer, message, cause)
}
class ReplyMessageNotFoundException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) : class ReplyMessageNotFoundException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
RequestException(response, plainAnswer, message, cause) RequestException(response, plainAnswer, message, cause) {
override fun createCopy(): BotException = ReplyMessageNotFoundException(response, plainAnswer, message, cause)
}
class MessageIsNotModifiedException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) : class MessageIsNotModifiedException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
RequestException(response, plainAnswer, message, cause) RequestException(response, plainAnswer, message, cause) {
override fun createCopy(): BotException = MessageIsNotModifiedException(response, plainAnswer, message, cause)
}
class MessageToEditNotFoundException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) : class MessageToEditNotFoundException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
RequestException(response, plainAnswer, message, cause) RequestException(response, plainAnswer, message, cause) {
override fun createCopy(): BotException = MessageToEditNotFoundException(response, plainAnswer, message, cause)
}
class InvalidPhotoDimensionsException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) : class InvalidPhotoDimensionsException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
RequestException(response, plainAnswer, message, cause) RequestException(response, plainAnswer, message, cause) {
override fun createCopy(): BotException = InvalidPhotoDimensionsException(response, plainAnswer, message, cause)
}
class WrongFileIdentifierException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) : class WrongFileIdentifierException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
RequestException(response, plainAnswer, message, cause) RequestException(response, plainAnswer, message, cause) {
override fun createCopy(): BotException = WrongFileIdentifierException(response, plainAnswer, message, cause)
}
class TooMuchRequestsException(val retryAfter: RetryAfterError, response: Response, plainAnswer: String, message: String?, cause: Throwable?) : class TooMuchRequestsException(val retryAfter: RetryAfterError, response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
RequestException(response, plainAnswer, message, cause) RequestException(response, plainAnswer, message, cause) {
override fun createCopy(): BotException = TooMuchRequestsException(retryAfter, response, plainAnswer, message, cause)
}
class GetUpdatesConflict(response: Response, plainAnswer: String, message: String?, cause: Throwable?) : class GetUpdatesConflict(response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
RequestException(response, plainAnswer, message, cause) RequestException(response, plainAnswer, message, cause) {
override fun createCopy(): BotException = GetUpdatesConflict(response, plainAnswer, message, cause)
}

View File

@ -77,21 +77,23 @@ class KtorRequestsExecutor(
val result = it.exceptionOrNull() ?.let { e -> val result = it.exceptionOrNull() ?.let { e ->
pipelineStepsHolder.onRequestException(request, e) ?.let { return@let it } pipelineStepsHolder.onRequestException(request, e) ?.let { return@let it }
if (e is ClientRequestException) { when (e) {
val exceptionResult = runCatchingSafely { is ClientRequestException -> {
val content = e.response.bodyAsText() val exceptionResult = runCatchingSafely {
val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content) val content = e.response.bodyAsText()
newRequestException( val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content)
responseObject, newRequestException(
content, responseObject,
"Can't get result object from $content" content,
) "Can't get result object from $content"
)
}
exceptionResult.exceptionOrNull() ?.let {
CommonBotException(cause = e)
} ?: exceptionResult.getOrThrow()
} }
exceptionResult.exceptionOrNull() ?.let { is BotException -> e
CommonBotException(cause = e) else -> CommonBotException(cause = e)
} ?: exceptionResult.getOrThrow()
} else {
CommonBotException(cause = e)
} }
} ?.let { Result.failure(it) } ?: it } ?.let { Result.failure(it) } ?: it
pipelineStepsHolder.onRequestReturnResult(result, request, callsFactories) pipelineStepsHolder.onRequestReturnResult(result, request, callsFactories)

View File

@ -3,8 +3,7 @@ package dev.inmo.tgbotapi.extensions.utils.updates.retrieving
import dev.inmo.micro_utils.coroutines.* import dev.inmo.micro_utils.coroutines.*
import dev.inmo.tgbotapi.bot.RequestsExecutor import dev.inmo.tgbotapi.bot.RequestsExecutor
import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.bot.exceptions.GetUpdatesConflict import dev.inmo.tgbotapi.bot.exceptions.*
import dev.inmo.tgbotapi.bot.exceptions.RequestException
import dev.inmo.tgbotapi.extensions.utils.updates.convertWithMediaGroupUpdates import dev.inmo.tgbotapi.extensions.utils.updates.convertWithMediaGroupUpdates
import dev.inmo.tgbotapi.extensions.utils.updates.lastUpdateIdentifier import dev.inmo.tgbotapi.extensions.utils.updates.lastUpdateIdentifier
import dev.inmo.tgbotapi.requests.GetUpdates import dev.inmo.tgbotapi.requests.GetUpdates
@ -101,10 +100,10 @@ fun TelegramBot.createAccumulatedUpdatesRetrieverFlow(
): Flow<Update> = longPollingFlow( ): Flow<Update> = longPollingFlow(
timeoutSeconds = 0, timeoutSeconds = 0,
exceptionsHandler = { exceptionsHandler = {
if (it is HttpRequestTimeoutException) { when {
throw CancellationException("Cancel due to absence of new updates") it is HttpRequestTimeoutException ||
} else { (it is CommonBotException && it.cause is HttpRequestTimeoutException) -> throw CancellationException("Cancel due to absence of new updates")
exceptionsHandler ?.invoke(it) else -> exceptionsHandler ?.invoke(it)
} }
}, },
allowedUpdates = allowedUpdates allowedUpdates = allowedUpdates