diff --git a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/HandleSafely.kt b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/HandleSafely.kt index 506932d5e8f..327a902cdcf 100644 --- a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/HandleSafely.kt +++ b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/HandleSafely.kt @@ -1,9 +1,9 @@ package dev.inmo.micro_utils.coroutines -import kotlinx.coroutines.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.supervisorScope import kotlin.coroutines.CoroutineContext import kotlin.coroutines.coroutineContext -import kotlin.reflect.KClass typealias ExceptionHandler = suspend (Throwable) -> T @@ -16,24 +16,13 @@ var defaultSafelyExceptionHandler: ExceptionHandler = { throw it } * Key for [SafelyExceptionHandler] which can be used in [CoroutineContext.get] to get current default * [SafelyExceptionHandler] */ -class SafelyExceptionHandlerKey() : CoroutineContext.Key> -private val nothingSafelyEceptionHandlerKey = SafelyExceptionHandlerKey() -private val unitSafelyEceptionHandlerKey = SafelyExceptionHandlerKey() +class SafelyExceptionHandlerKey : CoroutineContext.Key> -private val exceptionHandlersKeysCache = mutableMapOf<>() /** * Shortcut for creating instance of [SafelyExceptionHandlerKey] */ @Suppress("NOTHING_TO_INLINE") -inline fun safelyExceptionHandlerKey() = SafelyExceptionHandlerKey(T::class) - -/** - * Shortcut for getting instance of [SafelyExceptionHandler] from current [coroutineContext] - */ -@Suppress("NOTHING_TO_INLINE") -suspend inline fun safelyExceptionHandler() = coroutineContext[safelyExceptionHandlerKey()] -@Suppress("NOTHING_TO_INLINE") -inline fun ExceptionHandler.safelyExceptionHandler() = SafelyExceptionHandler(this, T::class) +inline fun safelyExceptionHandlerKey() = SafelyExceptionHandlerKey() /** * Wrapper for [ExceptionHandler] which can be used in [CoroutineContext] to set local (for [CoroutineContext]) default @@ -42,11 +31,11 @@ inline fun ExceptionHandler.safelyExceptionHandler() = Safe * @see SafelyExceptionHandlerKey * @see ExceptionHandler */ -class SafelyExceptionHandler( - val handler: ExceptionHandler, - returnKClass: KClass +class SafelyExceptionHandler( + val handler: ExceptionHandler ) : CoroutineContext.Element { - override val key: CoroutineContext.Key<*> = SafelyExceptionHandlerKey(returnKClass) + + override val key: CoroutineContext.Key<*> = safelyExceptionHandlerKey() } /** @@ -67,28 +56,18 @@ class SafelyExceptionHandler( * @see SafelyExceptionHandler */ suspend inline fun safely( - onException: ExceptionHandler = defaultSafelyExceptionHandler, - block: suspend CoroutineScope.() -> T + noinline onException: ExceptionHandler = defaultSafelyExceptionHandler, + noinline block: suspend CoroutineScope.() -> T ): T { - val contextHandler = if (onException === defaultSafelyExceptionHandler) { - coroutineContext[nothingSafelyEceptionHandlerKey] ?: - safelyExceptionHandler() ?.let { unitHandler -> - val handler = unitHandler.handler - SafelyExceptionHandler { - handler(it) - onException(it) - } - } ?: - onException.safelyExceptionHandler() - } else { - onException.safelyExceptionHandler() - } return try { - withContext(contextHandler) { - supervisorScope(block) - } + supervisorScope(block) } catch (e: Throwable) { - contextHandler.handler(e) + val handler = if (onException == defaultSafelyExceptionHandler) { + coroutineContext[safelyExceptionHandlerKey()] ?.handler ?: onException + } else { + onException + } + handler(e) } } diff --git a/coroutines/src/jvmTest/kotlin/dev/inmo/micro_utils/coroutines/HandleSafelyCoroutineContextTest.kt b/coroutines/src/jvmTest/kotlin/dev/inmo/micro_utils/coroutines/HandleSafelyCoroutineContextTest.kt deleted file mode 100644 index 445ba383006..00000000000 --- a/coroutines/src/jvmTest/kotlin/dev/inmo/micro_utils/coroutines/HandleSafelyCoroutineContextTest.kt +++ /dev/null @@ -1,32 +0,0 @@ -package dev.inmo.micro_utils.coroutines - -import kotlinx.coroutines.* -import kotlin.test.Test - -class HandleSafelyCoroutineContextTest { - @Test - fun testHandleSafelyCoroutineContext() { - val scope = CoroutineScope(Dispatchers.Default) - var contextHandlerHappen = false - var localHandlerHappen = false - val contextHandler: ExceptionHandler = { - contextHandlerHappen = true - } - val checkJob = scope.launch(Dispatchers.Default + contextHandler.safelyExceptionHandler()) { - safely { - safely( - { - localHandlerHappen = true - } - ) { - error("That must happen :)") - } - println(coroutineContext) - error("That must happen too:)") - } - } - launchSynchronously { checkJob.join() } - assert(contextHandlerHappen) - assert(localHandlerHappen) - } -} \ No newline at end of file