From e76c76d8d8c8f721c926d15c5a7d23d863d7f561 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Tue, 30 Jan 2024 22:38:43 +0800 Subject: [PATCH] =?UTF-8?q?pref:=20=E4=BC=98=E5=8C=96API=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E4=B8=AD=E5=8F=AF=E8=83=BD=E5=87=BA=E7=8E=B0=E7=9A=84=E5=AF=B9?= =?UTF-8?q?=E7=BB=93=E6=9E=9C=E7=9A=84=E5=8F=8D=E5=BA=8F=E5=88=97=E5=8C=96?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E7=9A=84=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../simbot/qguild/QQGuildApiException.kt | 27 ++++++++++++++++--- .../forte/simbot/qguild/api/ApiRequests.kt | 24 +++++++++++++---- .../forte/simbot/qguild/api/QQGuildApi.kt | 8 ++++-- 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/simbot-component-qq-guild-api/src/commonMain/kotlin/love/forte/simbot/qguild/QQGuildApiException.kt b/simbot-component-qq-guild-api/src/commonMain/kotlin/love/forte/simbot/qguild/QQGuildApiException.kt index fd35f906..d57d3c90 100644 --- a/simbot-component-qq-guild-api/src/commonMain/kotlin/love/forte/simbot/qguild/QQGuildApiException.kt +++ b/simbot-component-qq-guild-api/src/commonMain/kotlin/love/forte/simbot/qguild/QQGuildApiException.kt @@ -41,7 +41,19 @@ public open class QQGuildApiException : RuntimeException { public val value: Int public val description: String - public constructor(value: Int, description: String) : super("$value: $description") { + public constructor(value: Int, description: String) : this( + value = value, + description = description, + message = "$value: $description" + ) + + public constructor( + info: ErrInfo?, + value: Int, + description: String, + ) : this(value = value, description = description, message = "$value: $description; response info: $info") + + public constructor(value: Int, description: String, message: String) : super(message) { this.info = null this.value = value this.description = description @@ -51,14 +63,23 @@ public open class QQGuildApiException : RuntimeException { info: ErrInfo?, value: Int, description: String, - ) : super("$value: $description; response info: $info") { + message: String = "$value: $description; response info: $info" + ) : super(message) { this.info = info this.value = value this.description = description } - } +/** + * 当 API 相应结果反序列化失败 + */ +public open class QQGuildResultSerializationException( + value: Int, + description: String, + message: String = "$value: $description" +) : QQGuildApiException(value, description, message) + /** * @suppress */ diff --git a/simbot-component-qq-guild-api/src/commonMain/kotlin/love/forte/simbot/qguild/api/ApiRequests.kt b/simbot-component-qq-guild-api/src/commonMain/kotlin/love/forte/simbot/qguild/api/ApiRequests.kt index 0442d987..ab537ef7 100644 --- a/simbot-component-qq-guild-api/src/commonMain/kotlin/love/forte/simbot/qguild/api/ApiRequests.kt +++ b/simbot-component-qq-guild-api/src/commonMain/kotlin/love/forte/simbot/qguild/api/ApiRequests.kt @@ -28,16 +28,16 @@ import io.ktor.client.statement.* import io.ktor.client.utils.* import io.ktor.http.* import io.ktor.http.content.* +import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.SerializationException import kotlinx.serialization.StringFormat import kotlinx.serialization.builtins.serializer import kotlinx.serialization.descriptors.StructureKind import kotlinx.serialization.json.Json import love.forte.simbot.common.serialization.guessSerializer import love.forte.simbot.logger.isDebugEnabled -import love.forte.simbot.qguild.ErrInfo -import love.forte.simbot.qguild.QQGuild -import love.forte.simbot.qguild.QQGuildApiException +import love.forte.simbot.qguild.* import kotlin.contracts.ExperimentalContracts import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -212,16 +212,30 @@ internal fun checkStatus( status: HttpStatusCode, resp: HttpResponse, ) { + // 如果出现了序列化异常,抛出 QQGuildResultSerializationException + fun decodeFromStringWithCatch(deserializer: DeserializationStrategy, string: String): T { + return try { + decoder.decodeFromString(deserializer, remainingText) + } catch (serEx: SerializationException) { + // 反序列化异常 + throw QQGuildResultSerializationException(status.value, status.description, "Response(status=${status.value}) deserialization failed: ${serEx.message}").also { + it.initCause0(serEx) + } + } + } + + // TODO 201,202 异步操作成功,虽然说成功,但是会返回一个 error body,需要特殊处理 if (!status.isSuccess()) { - val info = decoder.decodeFromString(ErrInfo.serializer(), remainingText) + val info = decodeFromStringWithCatch(ErrInfo.serializer(), remainingText) + // throw err throw QQGuildApiException(info, status.value, status.description) } // 202 消息审核 if (status == HttpStatusCode.Accepted) { - val info = decoder.decodeFromString(ErrInfo.serializer(), remainingText) + val info = decodeFromStringWithCatch(ErrInfo.serializer(), remainingText) // maybe audited if (MessageAuditedException.isAuditResultCode(info.code)) { throw MessageAuditedException( diff --git a/simbot-component-qq-guild-api/src/commonMain/kotlin/love/forte/simbot/qguild/api/QQGuildApi.kt b/simbot-component-qq-guild-api/src/commonMain/kotlin/love/forte/simbot/qguild/api/QQGuildApi.kt index f8c7894a..dd4be9c7 100644 --- a/simbot-component-qq-guild-api/src/commonMain/kotlin/love/forte/simbot/qguild/api/QQGuildApi.kt +++ b/simbot-component-qq-guild-api/src/commonMain/kotlin/love/forte/simbot/qguild/api/QQGuildApi.kt @@ -25,8 +25,12 @@ import love.forte.simbot.logger.Logger import love.forte.simbot.logger.LoggerFactory import love.forte.simbot.qguild.QQGuild -@PublishedApi -internal val apiLogger: Logger = LoggerFactory.getLogger("love.forte.simbot.qguild.api") +/** + * 用于在 [QQGuildApi.request] 及其衍生API中输出相关日志的 [Logger]。 + * 开启 `love.forte.simbot.qguild.api` 的 `DEBUG` 级别日志可以得到更多在 API 请求过程中产生的信息。 + * 注意:这可能会暴露其中的参数、返回值等,请注意保护敏感信息。 + */ +public val apiLogger: Logger = LoggerFactory.getLogger("love.forte.simbot.qguild.api") /** * [有关 traceID](https://bot.q.qq.com/wiki/develop/api/openapi/error/error.html#%E6%9C%89%E5%85%B3-traceid)