From 81ad55b19f9b5db9a6ef63ea3ef1d3b0e9842c1f Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 11 Apr 2022 14:41:02 +0600 Subject: [PATCH] add KtorPipelineStepsHolder#onRequestReturnResult --- .../tgbotapi/bot/Ktor/KtorRequestsExecutor.kt | 77 ++++++++++--------- .../bot/ktor/KtorPipelineStepsHolder.kt | 16 +++- 2 files changed, 54 insertions(+), 39 deletions(-) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt index 16168229f7..c05d98fc14 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt @@ -75,46 +75,51 @@ class KtorRequestsExecutor( } override suspend fun execute(request: Request): T { - return safely( - { e -> - pipelineStepsHolder.onRequestException(request, e) ?.let { return@safely it } + return runCatching { + safely( + { e -> + pipelineStepsHolder.onRequestException(request, e) ?.let { return@safely it } - throw if (e is ClientRequestException) { - val content = e.response.readText() - val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content) - newRequestException( - responseObject, - content, - "Can't get result object from $content" - ) - } else { - e - } - } - ) { - pipelineStepsHolder.onBeforeSearchCallFactory(request, callsFactories) - requestsLimiter.limit { - var result: T? = null - lateinit var factoryHandledRequest: KtorCallFactory - for (potentialFactory in callsFactories) { - pipelineStepsHolder.onBeforeCallFactoryMakeCall(request, potentialFactory) - result = potentialFactory.makeCall( - client, - telegramAPIUrlsKeeper, - request, - jsonFormatter - ) - result = pipelineStepsHolder.onAfterCallFactoryMakeCall(result, request, potentialFactory) - if (result != null) { - factoryHandledRequest = potentialFactory - break + throw if (e is ClientRequestException) { + val content = e.response.readText() + val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content) + newRequestException( + responseObject, + content, + "Can't get result object from $content" + ) + } else { + e } - } - result ?.let { - pipelineStepsHolder.onRequestResultPresented(it, request, factoryHandledRequest, callsFactories) - } ?: pipelineStepsHolder.onRequestResultAbsent(request, callsFactories) ?: error("Can't execute request: $request") + } + ) { + pipelineStepsHolder.onBeforeSearchCallFactory(request, callsFactories) + requestsLimiter.limit { + var result: T? = null + lateinit var factoryHandledRequest: KtorCallFactory + for (potentialFactory in callsFactories) { + pipelineStepsHolder.onBeforeCallFactoryMakeCall(request, potentialFactory) + result = potentialFactory.makeCall( + client, + telegramAPIUrlsKeeper, + request, + jsonFormatter + ) + result = pipelineStepsHolder.onAfterCallFactoryMakeCall(result, request, potentialFactory) + if (result != null) { + factoryHandledRequest = potentialFactory + break + } + } + + result ?.let { + pipelineStepsHolder.onRequestResultPresented(it, request, factoryHandledRequest, callsFactories) + } ?: pipelineStepsHolder.onRequestResultAbsent(request, callsFactories) ?: error("Can't execute request: $request") + } } + }.let { + pipelineStepsHolder.onRequestReturnResult(it, request, callsFactories) } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/ktor/KtorPipelineStepsHolder.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/ktor/KtorPipelineStepsHolder.kt index f5b499e244..b1e8eb9db5 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/ktor/KtorPipelineStepsHolder.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/ktor/KtorPipelineStepsHolder.kt @@ -34,7 +34,7 @@ interface KtorPipelineStepsHolder { * Will always be called after [potentialFactory] has tried to make [request] and got some [result]. If returns * value - that value will be returned from [dev.inmo.tgbotapi.bot.RequestsExecutor.execute] instead */ - suspend fun onAfterCallFactoryMakeCall( + suspend fun onAfterCallFactoryMakeCall( result: T?, request: Request, potentialFactory: KtorCallFactory @@ -45,7 +45,7 @@ interface KtorPipelineStepsHolder { * handled [request] and returned [result]. If returns value - that value will be returned from * [dev.inmo.tgbotapi.bot.RequestsExecutor.execute] instead */ - suspend fun onRequestResultPresented( + suspend fun onRequestResultPresented( result: T, request: Request, resultCallFactory: KtorCallFactory, @@ -56,8 +56,18 @@ interface KtorPipelineStepsHolder { * Will be called when there is no [KtorCallFactory] from [callsFactories] which may handle [request]. If returns * value - that value will be returned from [dev.inmo.tgbotapi.bot.RequestsExecutor.execute] instead */ - suspend fun onRequestResultAbsent( + suspend fun onRequestResultAbsent( request: Request, callsFactories: List ): T? = null + + /** + * This step will be called when the [result] has been retrieved (or exception has happened). If returns value - + * that value will be returned from [dev.inmo.tgbotapi.bot.RequestsExecutor.execute] instead + */ + suspend fun onRequestReturnResult( + result: Result, + request: Request, + callsFactories: List + ): T = result.getOrThrow() }