Commit 2bfffa7b authored by Him188's avatar Him188

Fix network UnknownHostException handling

parent ae8d6e0c
...@@ -215,7 +215,9 @@ internal abstract class BotImpl<N : BotNetworkHandler> constructor( ...@@ -215,7 +215,9 @@ internal abstract class BotImpl<N : BotNetworkHandler> constructor(
init { init {
coroutineContext[Job]!!.invokeOnCompletion { throwable -> coroutineContext[Job]!!.invokeOnCompletion { throwable ->
network.close(throwable) kotlin.runCatching {
network.close(throwable)
}
offlineListener.cancel(CancellationException("Bot cancelled", throwable)) offlineListener.cancel(CancellationException("Bot cancelled", throwable))
// help GC release instances // help GC release instances
......
...@@ -38,12 +38,9 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.login.ConfigPushSvc ...@@ -38,12 +38,9 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.login.ConfigPushSvc
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.Heartbeat import net.mamoe.mirai.qqandroid.network.protocol.packet.login.Heartbeat
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.StatSvc import net.mamoe.mirai.qqandroid.network.protocol.packet.login.StatSvc
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.WtLogin import net.mamoe.mirai.qqandroid.network.protocol.packet.login.WtLogin
import net.mamoe.mirai.qqandroid.utils.NoRouteToHostException import net.mamoe.mirai.qqandroid.utils.*
import net.mamoe.mirai.qqandroid.utils.PlatformSocket
import net.mamoe.mirai.qqandroid.utils.SocketException
import net.mamoe.mirai.qqandroid.utils.io.readPacketExact import net.mamoe.mirai.qqandroid.utils.io.readPacketExact
import net.mamoe.mirai.qqandroid.utils.io.useBytes import net.mamoe.mirai.qqandroid.utils.io.useBytes
import net.mamoe.mirai.qqandroid.utils.retryCatching
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.jvm.JvmField import kotlin.jvm.JvmField
...@@ -137,6 +134,13 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo ...@@ -137,6 +134,13 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
} else { } else {
throw e throw e
} }
} catch (e: UnknownHostException) {
if (e is NoRouteToHostException || e.message?.contains("Network is unreachable") == true) {
logger.warning { "No route to host (Mostly due to no Internet connection). Retrying in 3s..." }
delay(3000)
} else {
throw e
}
} }
} }
logger.info { "Connected to server $host:$port" } logger.info { "Connected to server $host:$port" }
...@@ -627,6 +631,7 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo ...@@ -627,6 +631,7 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
check(bot.isActive) { "bot is dead therefore can't send ${this.commandName}" } check(bot.isActive) { "bot is dead therefore can't send ${this.commandName}" }
check(this@QQAndroidBotNetworkHandler.isActive) { "network is dead therefore can't send any packet" } check(this@QQAndroidBotNetworkHandler.isActive) { "network is dead therefore can't send any packet" }
check(channel.isOpen) { "network channel is closed" }
suspend fun doSendAndReceive(handler: PacketListener, data: Any, length: Int): E { suspend fun doSendAndReceive(handler: PacketListener, data: Any, length: Int): E {
when (data) { when (data) {
...@@ -637,10 +642,9 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo ...@@ -637,10 +642,9 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
logger.verbose { "Send: $commandName" } logger.verbose { "Send: $commandName" }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
return withTimeoutOrNull(timeoutMillis) { return withTimeout(timeoutMillis) {
handler.await() handler.await()
// 不要 `withTimeout`. timeout 的报错会不正常. } as E
} as E? ?: throw TimeoutException("timeout receiving response of $commandName")
} }
if (retry == 0) { if (retry == 0) {
......
...@@ -43,4 +43,5 @@ internal expect class PlatformSocket() : Closeable { ...@@ -43,4 +43,5 @@ internal expect class PlatformSocket() : Closeable {
} }
expect open class SocketException : IOException expect open class SocketException : IOException
expect class NoRouteToHostException : SocketException expect class NoRouteToHostException : SocketException
\ No newline at end of file expect class UnknownHostException : IOException
\ No newline at end of file
...@@ -201,4 +201,5 @@ internal actual class PlatformSocket : Closeable { ...@@ -201,4 +201,5 @@ internal actual class PlatformSocket : Closeable {
actual typealias NoRouteToHostException = java.net.NoRouteToHostException actual typealias NoRouteToHostException = java.net.NoRouteToHostException
actual typealias SocketException = SocketException actual typealias SocketException = SocketException
*/ */
\ No newline at end of file actual typealias UnknownHostException = java.net.UnknownHostException
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment