From dc36d0721712408ebf22961e91ebcb948cce6ada Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 7 Feb 2020 08:43:43 +0800 Subject: [PATCH] Fix exception handling --- .../event/internal/InternalEventListeners.kt | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt index b23bf6e63..5c8e0d3ce 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt @@ -1,15 +1,15 @@ package net.mamoe.mirai.event.internal -import kotlinx.coroutines.CompletableJob -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Job -import kotlinx.coroutines.withContext +import kotlinx.coroutines.* import net.mamoe.mirai.event.Listener import net.mamoe.mirai.event.ListeningStatus import net.mamoe.mirai.event.Subscribable import net.mamoe.mirai.utils.LockFreeLinkedList +import net.mamoe.mirai.utils.MiraiDebugAPI +import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.io.logStacktrace import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.coroutineContext import kotlin.jvm.JvmField import kotlin.reflect.KClass @@ -31,6 +31,7 @@ internal fun CoroutineScope.Handler(handler: suspend (E) -> L return Handler(coroutineContext[Job], coroutineContext, handler) } +private inline fun inline(block: () -> Unit) = block() /** * 事件处理器. */ @@ -39,6 +40,7 @@ internal class Handler @PublishedApi internal constructor(parentJob: Job?, private val subscriberContext: CoroutineContext, @JvmField val handler: suspend (E) -> ListeningStatus) : Listener, CompletableJob by Job(parentJob) { + @UseExperimental(MiraiDebugAPI::class) override suspend fun onEvent(event: E): ListeningStatus { if (isCompleted || isCancelled) return ListeningStatus.STOPPED if (!isActive) return ListeningStatus.LISTENING @@ -46,8 +48,17 @@ internal class Handler // Inherit context. withContext(subscriberContext) { handler.invoke(event) }.also { if (it == ListeningStatus.STOPPED) this.complete() } } catch (e: Throwable) { - e.logStacktrace() - // this.complete() // do not `completeExceptionally`, otherwise parentJob will fail. + subscriberContext[CoroutineExceptionHandler]?.handleException(subscriberContext, e) + ?: coroutineContext[CoroutineExceptionHandler]?.handleException(subscriberContext, e) + ?: inline { + @Suppress("DEPRECATION") + MiraiLogger.warning( + """Event processing: An exception occurred but no CoroutineExceptionHandler found, + either in coroutineContext from Handler job, or in subscriberContext""".trimIndent() + ) + e.logStacktrace("Event processing(No CoroutineExceptionHandler found)") + } + // this.complete() // do not `completeExceptionally`, otherwise parentJob will fai`l. // ListeningStatus.STOPPED // not stopping listening.