@@ -179,18 +179,22 @@ public fun createTestCoroutineScope(context: CoroutineContext = EmptyCoroutineCo
179
179
else -> throw IllegalArgumentException (" Dispatcher must implement TestDispatcher: $dispatcher " )
180
180
}
181
181
var scope: TestCoroutineScopeImpl ? = null
182
- val exceptionHandler = when (val exceptionHandler = context[CoroutineExceptionHandler ]) {
183
- is UncaughtExceptionCaptor -> exceptionHandler
184
- null -> {
185
- val lock = SynchronizedObject ()
186
- CoroutineExceptionHandler { _, throwable ->
182
+ val ownExceptionHandler = run {
183
+ val lock = SynchronizedObject ()
184
+ object : AbstractCoroutineContextElement (CoroutineExceptionHandler ), TestCoroutineScopeExceptionHandler {
185
+ override fun handleException (context : CoroutineContext , exception : Throwable ) {
187
186
val reported = synchronized(lock) {
188
- scope!! .reportException(throwable )
187
+ scope!! .reportException(exception )
189
188
}
190
189
if (! reported)
191
- throw throwable // let this exception crash everything
190
+ throw exception // let this exception crash everything
192
191
}
193
192
}
193
+ }
194
+ val exceptionHandler = when (val exceptionHandler = context[CoroutineExceptionHandler ]) {
195
+ is UncaughtExceptionCaptor -> exceptionHandler
196
+ null -> ownExceptionHandler
197
+ is TestCoroutineScopeExceptionHandler -> ownExceptionHandler
194
198
else -> throw IllegalArgumentException (
195
199
" A CoroutineExceptionHandler was passed to TestCoroutineScope. " +
196
200
" Please pass it as an argument to a `launch` or `async` block on an already-created scope " +
@@ -203,6 +207,10 @@ public fun createTestCoroutineScope(context: CoroutineContext = EmptyCoroutineCo
203
207
}
204
208
}
205
209
210
+ /* * A marker that shows that this [CoroutineExceptionHandler] was created for [TestCoroutineScope]. With this,
211
+ * constructing a new [TestCoroutineScope] with the [CoroutineScope.coroutineContext] of an existing one will override
212
+ * the exception handler, instead of failing. */
213
+ private interface TestCoroutineScopeExceptionHandler : CoroutineExceptionHandler
206
214
207
215
private inline val CoroutineContext .delayController: DelayController ?
208
216
get() {
0 commit comments