Commit dc36d072 authored by Him188's avatar Him188

Fix exception handling

parent d2b6f119
package net.mamoe.mirai.event.internal package net.mamoe.mirai.event.internal
import kotlinx.coroutines.CompletableJob import kotlinx.coroutines.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.withContext
import net.mamoe.mirai.event.Listener import net.mamoe.mirai.event.Listener
import net.mamoe.mirai.event.ListeningStatus import net.mamoe.mirai.event.ListeningStatus
import net.mamoe.mirai.event.Subscribable import net.mamoe.mirai.event.Subscribable
import net.mamoe.mirai.utils.LockFreeLinkedList 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 net.mamoe.mirai.utils.io.logStacktrace
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.coroutineContext
import kotlin.jvm.JvmField import kotlin.jvm.JvmField
import kotlin.reflect.KClass import kotlin.reflect.KClass
...@@ -31,6 +31,7 @@ internal fun <E : Subscribable> CoroutineScope.Handler(handler: suspend (E) -> L ...@@ -31,6 +31,7 @@ internal fun <E : Subscribable> CoroutineScope.Handler(handler: suspend (E) -> L
return Handler(coroutineContext[Job], coroutineContext, handler) return Handler(coroutineContext[Job], coroutineContext, handler)
} }
private inline fun inline(block: () -> Unit) = block()
/** /**
* 事件处理器. * 事件处理器.
*/ */
...@@ -39,6 +40,7 @@ internal class Handler<in E : Subscribable> ...@@ -39,6 +40,7 @@ internal class Handler<in E : Subscribable>
@PublishedApi internal constructor(parentJob: Job?, private val subscriberContext: CoroutineContext, @JvmField val handler: suspend (E) -> ListeningStatus) : @PublishedApi internal constructor(parentJob: Job?, private val subscriberContext: CoroutineContext, @JvmField val handler: suspend (E) -> ListeningStatus) :
Listener<E>, CompletableJob by Job(parentJob) { Listener<E>, CompletableJob by Job(parentJob) {
@UseExperimental(MiraiDebugAPI::class)
override suspend fun onEvent(event: E): ListeningStatus { override suspend fun onEvent(event: E): ListeningStatus {
if (isCompleted || isCancelled) return ListeningStatus.STOPPED if (isCompleted || isCancelled) return ListeningStatus.STOPPED
if (!isActive) return ListeningStatus.LISTENING if (!isActive) return ListeningStatus.LISTENING
...@@ -46,8 +48,17 @@ internal class Handler<in E : Subscribable> ...@@ -46,8 +48,17 @@ internal class Handler<in E : Subscribable>
// Inherit context. // Inherit context.
withContext(subscriberContext) { handler.invoke(event) }.also { if (it == ListeningStatus.STOPPED) this.complete() } withContext(subscriberContext) { handler.invoke(event) }.also { if (it == ListeningStatus.STOPPED) this.complete() }
} catch (e: Throwable) { } catch (e: Throwable) {
e.logStacktrace() subscriberContext[CoroutineExceptionHandler]?.handleException(subscriberContext, e)
// this.complete() // do not `completeExceptionally`, otherwise parentJob will fail. ?: 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 // ListeningStatus.STOPPED
// not stopping listening. // not stopping listening.
......
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