1 package kotlinx.coroutines.test 2 3 import kotlinx.coroutines.* 4 import kotlinx.coroutines.internal.* 5 import kotlin.coroutines.* 6 7 internal class TestCoroutineExceptionHandler : 8 AbstractCoroutineContextElement(CoroutineExceptionHandler), CoroutineExceptionHandler { 9 private val _exceptions = mutableListOf<Throwable>() 10 private val _lock = SynchronizedObject() 11 private var _coroutinesCleanedUp = false 12 13 @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") // do not remove the INVISIBLE_REFERENCE suppression: required in K2 handleExceptionnull14 override fun handleException(context: CoroutineContext, exception: Throwable) { 15 synchronized(_lock) { 16 if (_coroutinesCleanedUp) { 17 handleUncaughtCoroutineException(context, exception) 18 } 19 _exceptions += exception 20 } 21 } 22 23 val uncaughtExceptions: List<Throwable> <lambda>null24 get() = synchronized(_lock) { _exceptions.toList() } 25 cleanupTestCoroutinesnull26 fun cleanupTestCoroutines() { 27 synchronized(_lock) { 28 _coroutinesCleanedUp = true 29 val exception = _exceptions.firstOrNull() ?: return 30 // log the rest 31 _exceptions.drop(1).forEach { it.printStackTrace() } 32 throw exception 33 } 34 } 35 } 36