Don't catch Error while reconnecting and sending packet, fix #824

This commit is contained in:
Him188 2021-01-08 12:03:42 +08:00
parent b32090bf2a
commit 7dd7f48994
4 changed files with 69 additions and 11 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2020 Mamoe Technologies and contributors. * Copyright 2019-2021 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -26,9 +26,6 @@ import kotlin.time.ExperimentalTime
* *
* 群成员可能也是好友, 但他们在对象类型上不同. * 群成员可能也是好友, 但他们在对象类型上不同.
* 群成员可以通过 [asFriend] 得到相关好友对象. * 群成员可以通过 [asFriend] 得到相关好友对象.
*
* ## 相关的操作
* [Member.isFriend] 判断此成员是否为好友
*/ */
public interface NormalMember : Member { public interface NormalMember : Member {
/** /**

View File

@ -46,6 +46,32 @@ public inline fun <R> retryCatching(
return Result.failure(exception!!) return Result.failure(exception!!)
} }
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "RESULT_CLASS_IN_RETURN_TYPE")
@kotlin.internal.InlineOnly
@kotlin.internal.LowPriorityInOverloadResolution
public inline fun <R> retryCatchingExceptions(
n: Int,
except: KClass<out Exception>? = null,
block: (count: Int, lastException: Throwable?) -> R
): Result<R> {
require(n >= 0) {
"param n for retryCatching must not be negative"
}
var exception: Throwable? = null
repeat(n) {
try {
return Result.success(block(it, exception))
} catch (e: Exception) {
if (except?.isInstance(e) == true) {
return Result.failure(e)
}
exception?.addSuppressed(e)
exception = e
}
}
return Result.failure(exception!!)
}
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "RESULT_CLASS_IN_RETURN_TYPE") @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "RESULT_CLASS_IN_RETURN_TYPE")
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
@ -71,3 +97,38 @@ public inline fun <R> retryCatching(
} }
return Result.failure(exception!!) return Result.failure(exception!!)
} }
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "RESULT_CLASS_IN_RETURN_TYPE")
@kotlin.internal.InlineOnly
public inline fun <R> retryCatchingExceptions(
n: Int,
except: KClass<out Exception>? = null,
block: () -> R
): Result<R> {
require(n >= 0) {
"param n for retryCatching must not be negative"
}
var exception: Throwable? = null
repeat(n) {
try {
return Result.success(block())
} catch (e: Exception) {
if (except?.isInstance(e) == true) {
return Result.failure(e)
}
exception?.addSuppressed(e)
exception = e
}
}
return Result.failure(exception!!)
}
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "RESULT_CLASS_IN_RETURN_TYPE")
@kotlin.internal.InlineOnly
public inline fun <R> runCatchingExceptions(block: () -> R): Result<R> {
return try {
Result.success(block())
} catch (e: Exception) {
Result.failure(e)
}
}

View File

@ -164,7 +164,7 @@ internal abstract class AbstractBot<N : BotNetworkHandler> constructor(
private inner class Reconnect { private inner class Reconnect {
suspend fun reconnect(event: BotOfflineEvent): Boolean { suspend fun reconnect(event: BotOfflineEvent): Boolean {
while (true) { while (true) {
retryCatching<Unit>( retryCatchingExceptions<Unit>(
configuration.reconnectionRetryTimes, configuration.reconnectionRetryTimes,
except = LoginFailedException::class except = LoginFailedException::class
) { tryCount, _ -> ) { tryCount, _ ->
@ -229,7 +229,7 @@ internal abstract class AbstractBot<N : BotNetworkHandler> constructor(
} }
private suspend fun doInit() { private suspend fun doInit() {
retryCatching(5) { count, lastException -> retryCatchingExceptions(5) { count, lastException ->
if (count != 0) { if (count != 0) {
if (!isActive) { if (!isActive) {
logger.error("Cannot init due to fatal error") logger.error("Cannot init due to fatal error")

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2020 Mamoe Technologies and contributors. * Copyright 2019-2021 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -133,11 +133,11 @@ internal open class QQAndroidClient(
if (bot.client.serverList.isEmpty()) { if (bot.client.serverList.isEmpty()) {
bot.client.serverList.addAll(DefaultServerList) bot.client.serverList.addAll(DefaultServerList)
} }
retryCatching(bot.client.serverList.size, except = LoginFailedException::class) { retryCatchingExceptions(bot.client.serverList.size, except = LoginFailedException::class) l@{
val pair = bot.client.serverList[0] val pair = bot.client.serverList[0]
kotlin.runCatching { runCatchingExceptions {
block(pair.first, pair.second) block(pair.first, pair.second)
return@retryCatching return@l
}.getOrElse { }.getOrElse {
bot.client.serverList.remove(pair) bot.client.serverList.remove(pair)
if (it !is LoginFailedException) { if (it !is LoginFailedException) {