Skip to content

Commit

Permalink
Merge pull request #115 from simple-robot/dev/pref-api-log
Browse files Browse the repository at this point in the history
优化API请求中可能出现的对结果的反序列化异常的处理
  • Loading branch information
ForteScarlet authored Jan 30, 2024
2 parents 40f2543 + e76c76d commit 0b85a42
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -212,16 +212,30 @@ internal fun checkStatus(
status: HttpStatusCode,
resp: HttpResponse,
) {
// 如果出现了序列化异常,抛出 QQGuildResultSerializationException
fun <T> decodeFromStringWithCatch(deserializer: DeserializationStrategy<T>, 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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 0b85a42

Please sign in to comment.