Skip to content

Commit

Permalink
mamoe#2504,mamoe#2488 handle TimeoutCancellationException when resumi…
Browse files Browse the repository at this point in the history
…ng connection
  • Loading branch information
sandtechnology committed Feb 15, 2023
1 parent aec5e21 commit 68df39a
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,13 @@ internal abstract class AbstractKeepAliveNetworkHandlerSelector<H : NetworkHandl
// 不可挽救
exceptionCollector.throwLast()
}
} catch (e: TimeoutCancellationException) {
logIfEnabled { "... failed with TimeoutCancellationException: $e" }
exceptionCollector.collect(e)
close(e) // close H
logIfEnabled { "CLOSED instance" }
// 发包超时 可挽救
return false
} catch (e: Throwable) {
// 不可挽救
logIfEnabled { "... failed with unexpected: $e" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
package net.mamoe.mirai.internal.network.impl.common

import io.ktor.utils.io.errors.*
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.withTimeout
import net.mamoe.mirai.internal.BotAccount
import net.mamoe.mirai.internal.MockConfiguration
import net.mamoe.mirai.internal.QQAndroidBot
Expand All @@ -30,6 +32,7 @@ import net.mamoe.mirai.internal.network.handler.selector.KeepAliveNetworkHandler
import net.mamoe.mirai.internal.network.handler.selector.NetworkChannelException
import net.mamoe.mirai.internal.network.handler.selector.SelectorNetworkHandler
import net.mamoe.mirai.internal.network.handler.selectorLogger
import net.mamoe.mirai.internal.network.impl.HeartbeatFailedException
import net.mamoe.mirai.internal.network.protocol.packet.login.StatSvc
import net.mamoe.mirai.internal.test.runBlockingUnit
import net.mamoe.mirai.network.CustomLoginFailedException
Expand Down Expand Up @@ -91,6 +94,19 @@ internal class CommonNHBotNormalLoginTest : AbstractCommonNHTest() {
assertState(NetworkHandler.State.CLOSED)
}

// #1963
@Test
fun `test first login failure with internally handled exceptions3`() = runBlockingUnit {
setSsoProcessor {
//Throw TimeoutCancellationException
withTimeout(1) {
delay(1000)
}
}
assertFailsWith<TimeoutCancellationException>("test Connection reset by peer") { bot.login() }
assertState(NetworkHandler.State.CLOSED)
}

// 经过 #1963 考虑后在初次登录遇到任何错误都终止并传递异常
// @Test
// fun `test network broken`() = runBlockingUnit {
Expand Down Expand Up @@ -118,4 +134,34 @@ internal class CommonNHBotNormalLoginTest : AbstractCommonNHTest() {

assertState(NetworkHandler.State.OK)
}

// #2504, #2488
@Test
fun `test resume failed with TimeoutCancellationException`() = runBlockingUnit {
var first = true
var failCount = 3
setSsoProcessor {
if (first) {
first = false
} else {
if (failCount > 0) {
failCount--
//Throw TimeoutCancellationException
withTimeout(1) {
delay(1000)
}
}
}
}
val preTimes = bot.configuration.reconnectionRetryTimes
bot.configuration.reconnectionRetryTimes = 20
bot.login()
bot.network.close(HeartbeatFailedException("Heartbeat Timeout", RuntimeException("Timeout stub"), true))
eventDispatcher.joinBroadcast()
delay(1000L) // auto resume in BotOfflineEventMonitor
eventDispatcher.joinBroadcast()
bot.configuration.reconnectionRetryTimes = preTimes
assertState(NetworkHandler.State.OK)
}

}

0 comments on commit 68df39a

Please sign in to comment.