1 /* 2 * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 */ 4 5 package kotlinx.coroutines.test 6 7 import kotlinx.coroutines.* 8 import kotlin.coroutines.* 9 10 /** 11 * Access uncaught coroutine exceptions captured during test execution. 12 */ 13 @ExperimentalCoroutinesApi // Since 1.2.1, tentatively till 1.3.0 14 public interface UncaughtExceptionCaptor { 15 /** 16 * List of uncaught coroutine exceptions. 17 * 18 * The returned list is a copy of the currently caught exceptions. 19 * During [cleanupTestCoroutines] the first element of this list is rethrown if it is not empty. 20 */ 21 public val uncaughtExceptions: List<Throwable> 22 23 /** 24 * Call after the test completes to ensure that there were no uncaught exceptions. 25 * 26 * The first exception in uncaughtExceptions is rethrown. All other exceptions are 27 * printed using [Throwable.printStackTrace]. 28 * 29 * @throws Throwable the first uncaught exception, if there are any uncaught exceptions. 30 */ cleanupTestCoroutinesnull31 public fun cleanupTestCoroutines() 32 } 33 34 /** 35 * An exception handler that captures uncaught exceptions in tests. 36 */ 37 @ExperimentalCoroutinesApi // Since 1.2.1, tentatively till 1.3.0 38 public class TestCoroutineExceptionHandler : 39 AbstractCoroutineContextElement(CoroutineExceptionHandler), UncaughtExceptionCaptor, CoroutineExceptionHandler 40 { 41 private val _exceptions = mutableListOf<Throwable>() 42 43 /** @suppress **/ 44 override fun handleException(context: CoroutineContext, exception: Throwable) { 45 synchronized(_exceptions) { 46 _exceptions += exception 47 } 48 } 49 50 /** @suppress **/ 51 override val uncaughtExceptions: List<Throwable> 52 get() = synchronized(_exceptions) { _exceptions.toList() } 53 54 /** @suppress **/ 55 override fun cleanupTestCoroutines() { 56 synchronized(_exceptions) { 57 val exception = _exceptions.firstOrNull() ?: return 58 // log the rest 59 _exceptions.drop(1).forEach { it.printStackTrace() } 60 throw exception 61 } 62 } 63 } 64