diff --git a/CHANGELOG.md b/CHANGELOG.md index aabf659514..ae543f5dec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,22 @@ and size of retrieved updates is equal to 100 (max count of retrieved updates) * Extensions `getUpdates` now will receive only not nullable `limit` parameter +### 0.26.3 + +* `TelegramBotAPI`: + * `CallbackGameInlineKeyboardButton` was added + ([Issue-79](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/79), + [PR-80](https://github.com/InsanusMokrassar/TelegramBotAPI/pull/80)) + * `UnknownInlineKeyboardButton` was added. It is unavailable for creating, but you can receive it, for example, in + `InlineQueryResult` + * `Update` now will be created even if was `SerializationException` inside of creating the update instance - in this + case will be created `UnknownUpdateType` + * `UnknownUpdateType$rawJson` value now is included (`JsonElement`) + * **EXPERIMENTALLY** `BaseEditMessageUpdate#data` now is `CommonMessage<*>` + * Suspend inline function `handleSafely` was added + * `KtorRequestsExecutor` now use `handleSafely` instead of `try` with `supervisorScope` + * `UpdatesPolling` now use `handleSafely` instead of `try` with `supervisorScope` + ### 0.26.2 * `TelegramBotAPI`: diff --git a/TelegramBotAPI-extensions-api/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/api/updates/UpdatesPolling.kt b/TelegramBotAPI-extensions-api/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/api/updates/UpdatesPolling.kt index d74b77c559..9f18c87bc1 100644 --- a/TelegramBotAPI-extensions-api/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/api/updates/UpdatesPolling.kt +++ b/TelegramBotAPI-extensions-api/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/api/updates/UpdatesPolling.kt @@ -11,6 +11,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.update.MediaGroupUpdates import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update import com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.* import com.github.insanusmokrassar.TelegramBotAPI.utils.PreviewFeature +import com.github.insanusmokrassar.TelegramBotAPI.utils.handleSafely import io.ktor.client.features.HttpRequestTimeoutException import kotlinx.coroutines.* @@ -24,42 +25,40 @@ fun RequestsExecutor.startGettingOfUpdates( var lastUpdateIdentifier: UpdateIdentifier? = null while (isActive) { - try { - supervisorScope { - val updates = getUpdates( - offset = lastUpdateIdentifier?.plus(1), - timeout = timeoutSeconds, - allowed_updates = allowedUpdates - ).let { originalUpdates -> - val converted = originalUpdates.convertWithMediaGroupUpdates() - /** - * Dirty hack for cases when the media group was retrieved not fully: - * - * We are throw out the last media group and will reretrieve it again in the next get updates - * and it will guarantee that it is full - */ - if (originalUpdates.size == getUpdatesLimit.last && converted.last() is SentMediaGroupUpdate) { - converted - converted.last() - } else { - converted - } - } - - supervisorScope { - for (update in updates) { - updatesReceiver(update) - - lastUpdateIdentifier = update.lastUpdateIdentifier() - } + handleSafely( + { e -> + exceptionsHandler ?.invoke(e) + if (e is RequestException) { + delay(1000L) + } + } + ) { + val updates = getUpdates( + offset = lastUpdateIdentifier?.plus(1), + timeout = timeoutSeconds, + allowed_updates = allowedUpdates + ).let { originalUpdates -> + val converted = originalUpdates.convertWithMediaGroupUpdates() + /** + * Dirty hack for cases when the media group was retrieved not fully: + * + * We are throw out the last media group and will reretrieve it again in the next get updates + * and it will guarantee that it is full + */ + if (originalUpdates.size == getUpdatesLimit.last && converted.last() is SentMediaGroupUpdate) { + converted - converted.last() + } else { + converted + } + } + + handleSafely { + for (update in updates) { + updatesReceiver(update) + + lastUpdateIdentifier = update.lastUpdateIdentifier() } } - } catch (e: HttpRequestTimeoutException) { - exceptionsHandler ?.invoke(e) // it is ok due to mechanism of long polling - } catch (e: RequestException) { - exceptionsHandler ?.invoke(e) // it is not ok, but in most cases it will mean that there is some limit for requests count - delay(1000L) - } catch (e: Exception) { - exceptionsHandler ?.invoke(e) } } } diff --git a/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/KtorRequestsExecutor.kt b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/KtorRequestsExecutor.kt index ae1f2a4407..5f8bc97d5f 100644 --- a/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/KtorRequestsExecutor.kt +++ b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/KtorRequestsExecutor.kt @@ -9,7 +9,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.bot.settings.limiters.RequestL import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request import com.github.insanusmokrassar.TelegramBotAPI.types.Response import com.github.insanusmokrassar.TelegramBotAPI.types.RetryAfterError -import com.github.insanusmokrassar.TelegramBotAPI.utils.TelegramAPIUrlsKeeper +import com.github.insanusmokrassar.TelegramBotAPI.utils.* import com.github.insanusmokrassar.TelegramBotAPI.utils.nonstrictJsonFormat import io.ktor.client.HttpClient import io.ktor.client.call.receive @@ -17,7 +17,6 @@ import io.ktor.client.features.* import io.ktor.client.statement.HttpStatement import io.ktor.client.statement.readText import kotlinx.coroutines.delay -import kotlinx.coroutines.supervisorScope import kotlinx.serialization.json.Json class KtorRequestsExecutor( @@ -43,54 +42,56 @@ class KtorRequestsExecutor( } override suspend fun execute(request: Request): T { - return try { - supervisorScope { - requestsLimiter.limit { - var statement: HttpStatement? = null - for (factory in callsFactories) { - statement = factory.prepareCall( - client, - telegramAPIUrlsKeeper.commonAPIUrl, - request - ) - if (statement != null) { - break - } - } - - val response = statement?.execute() ?: throw IllegalArgumentException("Can't execute request: $request") - val content = response.receive() + return handleSafely( + { e -> + throw if (e is ClientRequestException) { + val content = e.response.readText() val responseObject = jsonFormatter.parse(Response.serializer(), content) - - (responseObject.result?.let { - jsonFormatter.fromJson(request.resultDeserializer, it) - } ?: responseObject.parameters?.let { - val error = it.error - if (error is RetryAfterError) { - delay(error.leftToRetry) - execute(request) - } else { - null - } - } ?: response.let { - throw newRequestException( - responseObject, - content, - "Can't get result object from $content" - ) - }) + newRequestException( + responseObject, + content, + "Can't get result object from $content" + ) + } else { + e } } - } catch (e: ClientRequestException) { - val content = e.response.readText() - val responseObject = jsonFormatter.parse(Response.serializer(), content) - throw newRequestException( - responseObject, - content, - "Can't get result object from $content" - ) - } catch (e: Exception) { - throw e + ) { + requestsLimiter.limit { + var statement: HttpStatement? = null + for (factory in callsFactories) { + statement = factory.prepareCall( + client, + telegramAPIUrlsKeeper.commonAPIUrl, + request + ) + if (statement != null) { + break + } + } + + val response = statement?.execute() ?: throw IllegalArgumentException("Can't execute request: $request") + val content = response.receive() + val responseObject = jsonFormatter.parse(Response.serializer(), content) + + (responseObject.result?.let { + jsonFormatter.fromJson(request.resultDeserializer, it) + } ?: responseObject.parameters?.let { + val error = it.error + if (error is RetryAfterError) { + delay(error.leftToRetry) + execute(request) + } else { + null + } + } ?: response.let { + throw newRequestException( + responseObject, + content, + "Can't get result object from $content" + ) + }) + } } } diff --git a/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/Common.kt b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/Common.kt index d0142f6a8b..3061fec7b9 100644 --- a/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/Common.kt +++ b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/Common.kt @@ -82,6 +82,7 @@ const val containsMasksField = "contains_masks" const val resultIdField = "result_id" const val inlineMessageIdField = "inline_message_id" const val callbackDataField = "callback_data" +const val callbackGameField = "callback_game" const val callbackQueryIdField = "callback_query_id" const val inlineQueryIdField = "inline_query_id" const val inlineKeyboardField = "inline_keyboard" diff --git a/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/buttons/InlineKeyboardButtons/InlineKeyboardButton.kt b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/buttons/InlineKeyboardButtons/InlineKeyboardButton.kt index 0c2da03af1..0e5c18508e 100644 --- a/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/buttons/InlineKeyboardButtons/InlineKeyboardButton.kt +++ b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/buttons/InlineKeyboardButtons/InlineKeyboardButton.kt @@ -1,14 +1,23 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.buttons.InlineKeyboardButtons import com.github.insanusmokrassar.TelegramBotAPI.types.* +import com.github.insanusmokrassar.TelegramBotAPI.types.games.CallbackGame import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject @Serializable(InlineKeyboardButtonSerializer::class) sealed class InlineKeyboardButton { abstract val text: String } +@Serializable +data class UnknownInlineKeyboardButton internal constructor( + override val text: String, + val rawData: JsonElement +) : InlineKeyboardButton() + @Serializable data class PayInlineKeyboardButton( override val text: String, @@ -24,6 +33,14 @@ data class CallbackDataInlineKeyboardButton( val callbackData: String ) : InlineKeyboardButton() +@Serializable +data class CallbackGameInlineKeyboardButton( + @SerialName(textField) + override val text: String, + @SerialName(callbackGameField) + val callbackGame: CallbackGame +) : InlineKeyboardButton() + @Serializable data class LoginURLInlineKeyboardButton( override val text: String, diff --git a/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/buttons/InlineKeyboardButtons/InlineKeyboardButtonSerializer.kt b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/buttons/InlineKeyboardButtons/InlineKeyboardButtonSerializer.kt index 463b6608cb..ea575f1d0e 100644 --- a/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/buttons/InlineKeyboardButtons/InlineKeyboardButtonSerializer.kt +++ b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/buttons/InlineKeyboardButtons/InlineKeyboardButtonSerializer.kt @@ -3,8 +3,7 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.buttons.InlineKeyboardB import com.github.insanusmokrassar.TelegramBotAPI.types.* import com.github.insanusmokrassar.TelegramBotAPI.utils.nonstrictJsonFormat import kotlinx.serialization.* -import kotlinx.serialization.json.JsonElementSerializer -import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.* internal object InlineKeyboardButtonSerializer : KSerializer { override val descriptor: SerialDescriptor = SerialDescriptor( @@ -12,22 +11,25 @@ internal object InlineKeyboardButtonSerializer : KSerializer { + private fun resolveSerializer(json: JsonObject): KSerializer? { return when { json[callbackDataField] != null -> CallbackDataInlineKeyboardButton.serializer() + json[callbackGameField] != null -> CallbackGameInlineKeyboardButton.serializer() json[loginUrlField] != null -> LoginURLInlineKeyboardButton.serializer() json[payField] != null -> PayInlineKeyboardButton.serializer() json[switchInlineQueryField] != null -> SwitchInlineQueryInlineKeyboardButton.serializer() json[switchInlineQueryCurrentChatField] != null -> SwitchInlineQueryCurrentChatInlineKeyboardButton.serializer() json[urlField] != null -> URLInlineKeyboardButton.serializer() - else -> throw IllegalArgumentException("Can't find correct serializer for inline button serialized as $json") + else -> null } } override fun deserialize(decoder: Decoder): InlineKeyboardButton { val json = JsonElementSerializer.deserialize(decoder) - return nonstrictJsonFormat.fromJson(resolveSerializer(json.jsonObject), json) + return (json as? JsonObject) ?.let { resolveSerializer(it) } ?.let { + nonstrictJsonFormat.fromJson(it, json) + } ?: UnknownInlineKeyboardButton("", json) } override fun serialize(encoder: Encoder, value: InlineKeyboardButton) { @@ -38,6 +40,8 @@ internal object InlineKeyboardButtonSerializer : KSerializer SwitchInlineQueryInlineKeyboardButton.serializer().serialize(encoder, value) is SwitchInlineQueryCurrentChatInlineKeyboardButton -> SwitchInlineQueryCurrentChatInlineKeyboardButton.serializer().serialize(encoder, value) is URLInlineKeyboardButton -> URLInlineKeyboardButton.serializer().serialize(encoder, value) + is CallbackGameInlineKeyboardButton -> CallbackGameInlineKeyboardButton.serializer().serialize(encoder, value) + is UnknownInlineKeyboardButton -> JsonElementSerializer.serialize(encoder, value.rawData) } } } diff --git a/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/EditChannelPostUpdate.kt b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/EditChannelPostUpdate.kt index 9fa544832c..6d07ed5db5 100644 --- a/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/EditChannelPostUpdate.kt +++ b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/EditChannelPostUpdate.kt @@ -1,10 +1,10 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.update import com.github.insanusmokrassar.TelegramBotAPI.types.UpdateIdentifier -import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.Message +import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.CommonMessage import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.BaseEditMessageUpdate data class EditChannelPostUpdate( override val updateId: UpdateIdentifier, - override val data: Message + override val data: CommonMessage<*> ) : BaseEditMessageUpdate diff --git a/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/EditMessageUpdate.kt b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/EditMessageUpdate.kt index ea9b4b8be9..6062b9d672 100644 --- a/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/EditMessageUpdate.kt +++ b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/EditMessageUpdate.kt @@ -1,10 +1,10 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.update import com.github.insanusmokrassar.TelegramBotAPI.types.UpdateIdentifier -import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.Message +import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.CommonMessage import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.BaseEditMessageUpdate data class EditMessageUpdate( override val updateId: UpdateIdentifier, - override val data: Message + override val data: CommonMessage<*> ) : BaseEditMessageUpdate diff --git a/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/RawUpdate.kt b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/RawUpdate.kt index 5ccd666095..f96d60bdb2 100644 --- a/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/RawUpdate.kt +++ b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/RawUpdate.kt @@ -4,7 +4,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.CallbackQuery.RawCallbac import com.github.insanusmokrassar.TelegramBotAPI.types.InlineQueries.ChosenInlineResult.RawChosenInlineResult import com.github.insanusmokrassar.TelegramBotAPI.types.InlineQueries.query.RawInlineQuery import com.github.insanusmokrassar.TelegramBotAPI.types.UpdateIdentifier -import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.Message +import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.* import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.TelegramBotAPIMessageDeserializeOnlySerializer import com.github.insanusmokrassar.TelegramBotAPI.types.payments.PreCheckoutQuery import com.github.insanusmokrassar.TelegramBotAPI.types.payments.ShippingQuery @@ -13,8 +13,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.polls.PollAnswer import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.UnknownUpdateType import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update import com.github.insanusmokrassar.TelegramBotAPI.types.updateIdField -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable +import kotlinx.serialization.* import kotlinx.serialization.json.JsonElement @Serializable @@ -22,11 +21,11 @@ internal data class RawUpdate constructor( @SerialName(updateIdField) val updateId: UpdateIdentifier, @Serializable(TelegramBotAPIMessageDeserializeOnlySerializer::class) - private val edited_message: Message? = null, + private val edited_message: CommonMessage<*>? = null, @Serializable(TelegramBotAPIMessageDeserializeOnlySerializer::class) private val message: Message? = null, @Serializable(TelegramBotAPIMessageDeserializeOnlySerializer::class) - private val edited_channel_post: Message? = null, + private val edited_channel_post: CommonMessage<*>? = null, @Serializable(TelegramBotAPIMessageDeserializeOnlySerializer::class) private val channel_post: Message? = null, private val inline_query: RawInlineQuery? = null, @@ -42,25 +41,34 @@ internal data class RawUpdate constructor( * @return One of children of [Update] interface or null in case of unknown type of update */ fun asUpdate(raw: JsonElement): Update { - return initedUpdate ?: when { - edited_message != null -> EditMessageUpdate(updateId, edited_message) - message != null -> MessageUpdate(updateId, message) - edited_channel_post != null -> EditChannelPostUpdate(updateId, edited_channel_post) - channel_post != null -> ChannelPostUpdate(updateId, channel_post) + return initedUpdate ?: try { + when { + edited_message != null -> EditMessageUpdate(updateId, edited_message) + message != null -> MessageUpdate(updateId, message) + edited_channel_post != null -> EditChannelPostUpdate(updateId, edited_channel_post) + channel_post != null -> ChannelPostUpdate(updateId, channel_post) - chosen_inline_result != null -> ChosenInlineResultUpdate(updateId, chosen_inline_result.asChosenInlineResult) - inline_query != null -> InlineQueryUpdate(updateId, inline_query.asInlineQuery) - callback_query != null -> CallbackQueryUpdate( + chosen_inline_result != null -> ChosenInlineResultUpdate(updateId, chosen_inline_result.asChosenInlineResult) + inline_query != null -> InlineQueryUpdate(updateId, inline_query.asInlineQuery) + callback_query != null -> CallbackQueryUpdate( + updateId, + callback_query.asCallbackQuery(raw.jsonObject["callback_query"].toString()) + ) + shipping_query != null -> ShippingQueryUpdate(updateId, shipping_query) + pre_checkout_query != null -> PreCheckoutQueryUpdate(updateId, pre_checkout_query) + poll != null -> PollUpdate(updateId, poll) + poll_answer != null -> PollAnswerUpdate(updateId, poll_answer) + else -> UnknownUpdateType( + updateId, + raw.toString(), + raw + ) + } + } catch (e: SerializationException) { + UnknownUpdateType( updateId, - callback_query.asCallbackQuery(raw.jsonObject["callback_query"].toString()) - ) - shipping_query != null -> ShippingQueryUpdate(updateId, shipping_query) - pre_checkout_query != null -> PreCheckoutQueryUpdate(updateId, pre_checkout_query) - poll != null -> PollUpdate(updateId, poll) - poll_answer != null -> PollAnswerUpdate(updateId, poll_answer) - else -> UnknownUpdateType( - updateId, - raw.toString() + raw.toString(), + raw ) }.also { initedUpdate = it diff --git a/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/abstracts/BaseEditMessageUpdate.kt b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/abstracts/BaseEditMessageUpdate.kt index c7ce6ea1b0..9b1ab9cf9d 100644 --- a/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/abstracts/BaseEditMessageUpdate.kt +++ b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/abstracts/BaseEditMessageUpdate.kt @@ -1,3 +1,7 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts -interface BaseEditMessageUpdate : BaseMessageUpdate +import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.CommonMessage + +interface BaseEditMessageUpdate : BaseMessageUpdate { + override val data: CommonMessage<*> +} diff --git a/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/abstracts/Update.kt b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/abstracts/Update.kt index 536fd33827..d361301b31 100644 --- a/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/abstracts/Update.kt +++ b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/abstracts/Update.kt @@ -4,6 +4,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.UpdateIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.update.RawUpdate import com.github.insanusmokrassar.TelegramBotAPI.utils.nonstrictJsonFormat import kotlinx.serialization.* +import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonElementSerializer interface Update { @@ -13,7 +14,8 @@ interface Update { data class UnknownUpdateType( override val updateId: UpdateIdentifier, - override val data: String + override val data: String, + val rawJson: JsonElement ) : Update internal object UpdateSerializerWithoutDeserialization : KSerializer { diff --git a/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/HandleSafely.kt b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/HandleSafely.kt new file mode 100644 index 0000000000..6e8deeaae8 --- /dev/null +++ b/TelegramBotAPI/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/HandleSafely.kt @@ -0,0 +1,21 @@ +package com.github.insanusmokrassar.TelegramBotAPI.utils + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.supervisorScope + +/** + * It will run [block] inside of [supervisorScope] to avoid problems with catching of exceptions + * + * @param [onException] Will be called when happen exception inside of [block]. By default will throw exception - this + * exception will be available for catching + */ +suspend inline fun handleSafely( + noinline onException: suspend (Exception) -> T = { throw it }, + noinline block: suspend CoroutineScope.() -> T +): T { + return try { + supervisorScope(block) + } catch (e: Exception) { + onException(e) + } +} diff --git a/gradle.properties b/gradle.properties index cd735c2204..019b89b8dd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,6 +7,6 @@ uuid_version=0.1.0 ktor_version=1.3.2 library_group=com.github.insanusmokrassar -library_version=0.26.2 +library_version=0.26.3 gradle_bintray_plugin_version=1.8.4