Quellcode durchsuchen

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

Him188 vor 5 Jahren
Ursprung
Commit
7dd7f48994

+ 1 - 4
mirai-core-api/src/commonMain/kotlin/contact/NormalMember.kt

@@ -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 许可证的约束, 可以在以下链接找到该许可证.
  *  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] 得到相关好友对象.
- *
- * ## 相关的操作
- * [Member.isFriend] 判断此成员是否为好友
  */
 public interface NormalMember : Member {
     /**

+ 62 - 1
mirai-core-utils/src/commonMain/kotlin/StandardUtils.kt

@@ -46,6 +46,32 @@ public inline fun <R> retryCatching(
     return Result.failure(exception!!)
 }
 
+@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "RESULT_CLASS_IN_RETURN_TYPE")
[email protected]
[email protected]
+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")
 @kotlin.internal.InlineOnly
@@ -70,4 +96,39 @@ public inline fun <R> retryCatching(
         }
     }
     return Result.failure(exception!!)
-}
+}
+
+@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "RESULT_CLASS_IN_RETURN_TYPE")
[email protected]
+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")
[email protected]
+public inline fun <R> runCatchingExceptions(block: () -> R): Result<R> {
+    return try {
+        Result.success(block())
+    } catch (e: Exception) {
+        Result.failure(e)
+    }
+}

+ 2 - 2
mirai-core/src/commonMain/kotlin/AbstractBot.kt

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

+ 4 - 4
mirai-core/src/commonMain/kotlin/network/QQAndroidClient.kt

@@ -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 许可证的约束, 可以在以下链接找到该许可证.
  *  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()) {
             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]
-            kotlin.runCatching {
+            runCatchingExceptions {
                 block(pair.first, pair.second)
-                return@retryCatching
+                return@l
             }.getOrElse {
                 bot.client.serverList.remove(pair)
                 if (it !is LoginFailedException) {