Skip to content

Commit 71125e3

Browse files
authored
Do not propagate exceptions to CoroutineExceptionHandler in 'future' builder if it has been cancelled in order to be consistent with other future implementations (#3580)
Fixes #3452
1 parent 4102f90 commit 71125e3

File tree

2 files changed

+7
-9
lines changed

2 files changed

+7
-9
lines changed

kotlinx-coroutines-core/jdk8/src/future/Future.kt

+6-4
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,12 @@ private class CompletableFutureCoroutine<T>(
5858
}
5959

6060
override fun onCancelled(cause: Throwable, handled: Boolean) {
61-
if (!future.completeExceptionally(cause) && !handled) {
62-
// prevents loss of exception that was not handled by parent & could not be set to CompletableFuture
63-
handleCoroutineException(context, cause)
64-
}
61+
/*
62+
* Here we can potentially lose the cause if the failure is racing with future's
63+
* external cancellation. We are consistent with other future implementations
64+
* (LF, FT, CF) and give up on such exception.
65+
*/
66+
future.completeExceptionally(cause)
6567
}
6668
}
6769

kotlinx-coroutines-core/jvm/test/jdk8/future/FutureTest.kt

+1-5
Original file line numberDiff line numberDiff line change
@@ -392,11 +392,7 @@ class FutureTest : TestBase() {
392392
}
393393

394394
@Test
395-
fun testUnhandledExceptionOnExternalCompletion() = runTest(
396-
unhandled = listOf(
397-
{ it -> it is TestException } // exception is unhandled because there is no parent
398-
)
399-
) {
395+
fun testUnhandledExceptionOnExternalCompletionIsNotReported() = runTest {
400396
expect(1)
401397
// No parent here (NonCancellable), so nowhere to propagate exception
402398
val result = future(NonCancellable + Dispatchers.Unconfined) {

0 commit comments

Comments
 (0)