Unwrap NetworkException on logon failure

This commit is contained in:
Him188 2021-06-06 13:52:09 +08:00
parent 7739c4db80
commit dadff42718
4 changed files with 18 additions and 15 deletions

View File

@ -109,8 +109,10 @@ public inline fun <R> runUnwrapCancellationException(block: () -> R): R {
} }
} }
public fun Throwable.unwrapCancellationException(): Throwable { public fun Throwable.unwrapCancellationException(): Throwable = unwrap<CancellationException>()
if (this !is CancellationException) return this
public inline fun <reified E> Throwable.unwrap(): Throwable {
if (this !is E) return this
if (suppressedExceptions.isNotEmpty()) return this if (suppressedExceptions.isNotEmpty()) return this
return this.findCause { it !is CancellationException } ?: this return this.findCause { it !is E } ?: this
} }

View File

@ -205,6 +205,7 @@ public inline fun Throwable.findCause(maxDepth: Int = 20, filter: (Throwable) ->
var depth = 0 var depth = 0
var rootCause: Throwable? = this var rootCause: Throwable? = this
while (true) { while (true) {
if (rootCause?.cause === rootCause) return rootCause
val current = rootCause?.cause ?: return null val current = rootCause?.cause ?: return null
if (filter(current)) return current if (filter(current)) return current
rootCause = rootCause.cause rootCause = rootCause.cause

View File

@ -23,12 +23,10 @@ import net.mamoe.mirai.internal.contact.uin
import net.mamoe.mirai.internal.network.component.ComponentStorage import net.mamoe.mirai.internal.network.component.ComponentStorage
import net.mamoe.mirai.internal.network.components.SsoProcessor import net.mamoe.mirai.internal.network.components.SsoProcessor
import net.mamoe.mirai.internal.network.handler.NetworkHandler import net.mamoe.mirai.internal.network.handler.NetworkHandler
import net.mamoe.mirai.internal.network.handler.selector.NetworkException
import net.mamoe.mirai.internal.network.impl.netty.asCoroutineExceptionHandler import net.mamoe.mirai.internal.network.impl.netty.asCoroutineExceptionHandler
import net.mamoe.mirai.supervisorJob import net.mamoe.mirai.supervisorJob
import net.mamoe.mirai.utils.BotConfiguration import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.childScopeContext
import net.mamoe.mirai.utils.info
import kotlin.collections.set import kotlin.collections.set
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
@ -118,10 +116,11 @@ internal abstract class AbstractBot constructor(
try { try {
network.resumeConnection() network.resumeConnection()
} catch (e: Throwable) { // failed to init } catch (e: Throwable) { // failed to init
val cause = e.unwrap<NetworkException>()
if (!components[SsoProcessor].firstLoginSucceed) { if (!components[SsoProcessor].firstLoginSucceed) {
this.close() // failed to do first login. this.close(cause) // failed to do first login.
} }
throw e throw cause
} }
logger.info { "Bot login successful." } logger.info { "Bot login successful." }
} }

View File

@ -12,16 +12,13 @@
package net.mamoe.mirai.internal.network.handler package net.mamoe.mirai.internal.network.handler
import io.netty.channel.Channel import io.netty.channel.Channel
import kotlinx.coroutines.CancellationException
import net.mamoe.mirai.internal.network.impl.netty.AbstractNettyNHTest import net.mamoe.mirai.internal.network.impl.netty.AbstractNettyNHTest
import net.mamoe.mirai.internal.network.impl.netty.TestNettyNH import net.mamoe.mirai.internal.network.impl.netty.TestNettyNH
import net.mamoe.mirai.internal.test.runBlockingUnit import net.mamoe.mirai.internal.test.runBlockingUnit
import net.mamoe.mirai.utils.TestOnly import net.mamoe.mirai.utils.TestOnly
import net.mamoe.mirai.utils.getRootCause
import org.junit.jupiter.api.assertThrows import org.junit.jupiter.api.assertThrows
import java.net.SocketAddress import java.net.SocketAddress
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertIs
internal class KeepAliveNetworkHandlerSelectorRealTest : AbstractNettyNHTest() { internal class KeepAliveNetworkHandlerSelectorRealTest : AbstractNettyNHTest() {
@ -42,9 +39,13 @@ internal class KeepAliveNetworkHandlerSelectorRealTest : AbstractNettyNHTest() {
// selector should not tolerant any exception during state initialization, or in the Jobs launched in states. // selector should not tolerant any exception during state initialization, or in the Jobs launched in states.
val selector = TestSelector(3) { createHandler() } val selector = TestSelector(3) { createHandler() }
assertThrows<CancellationException> { selector.awaitResumeInstance() }.run { assertThrows<Throwable> { selector.awaitResumeInstance() }
assertIs<MyException>(getRootCause())
} }
@Test
fun `should unwrap exception`() = runBlockingUnit {
val selector = TestSelector(3) { createHandler() }
assertThrows<MyException> { selector.awaitResumeInstance() }
} }
} }