File tree Expand file tree Collapse file tree 4 files changed +38
-2
lines changed Expand file tree Collapse file tree 4 files changed +38
-2
lines changed Original file line number Diff line number Diff line change @@ -70,7 +70,9 @@ private class ListenableFutureCoroutine<T>(
70
70
}
71
71
72
72
override fun onCompletedExceptionally (exception : Throwable ) {
73
- completion.setException(exception)
73
+ if (! completion.setException(exception)) {
74
+ handleCoroutineException(parentContext, exception, this )
75
+ }
74
76
}
75
77
}
76
78
Original file line number Diff line number Diff line change @@ -300,6 +300,22 @@ class ListenableFutureTest : TestBase() {
300
300
finish(3 )
301
301
}
302
302
303
+ @Test
304
+ fun testExceptionOnExternalCancellation () = runTest(expected = {it is TestException }) {
305
+ expect(1 )
306
+ val result = future(Dispatchers .Unconfined ) {
307
+ try {
308
+ delay(Long .MAX_VALUE )
309
+ } finally {
310
+ expect(2 )
311
+ throw TestException ()
312
+ }
313
+ }
314
+
315
+ result.cancel(true )
316
+ finish(3 )
317
+ }
318
+
303
319
private inline fun <reified T : Throwable > ListenableFuture <* >.checkFutureException (vararg suppressed : KClass <out Throwable >) {
304
320
val e = assertFailsWith<ExecutionException > { get() }
305
321
val cause = e.cause!!
Original file line number Diff line number Diff line change @@ -58,7 +58,9 @@ private class CompletableFutureCoroutine<T>(
58
58
}
59
59
60
60
override fun onCompletedExceptionally (exception : Throwable ) {
61
- completion.completeExceptionally(exception)
61
+ if (! completion.completeExceptionally(exception)) {
62
+ handleCoroutineException(parentContext, exception, this )
63
+ }
62
64
}
63
65
}
64
66
Original file line number Diff line number Diff line change @@ -411,6 +411,22 @@ class FutureTest : TestBase() {
411
411
finish(3 )
412
412
}
413
413
414
+ @Test
415
+ fun testExceptionOnExternalCompletion () = runTest(expected = {it is TestException }) {
416
+ expect(1 )
417
+ val result = future(Dispatchers .Unconfined ) {
418
+ try {
419
+ delay(Long .MAX_VALUE )
420
+ } finally {
421
+ expect(2 )
422
+ throw TestException ()
423
+ }
424
+ }
425
+
426
+ result.complete(Unit )
427
+ finish(3 )
428
+ }
429
+
414
430
private inline fun <reified T : Throwable > CompletableFuture <* >.checkFutureException (vararg suppressed : KClass <out Throwable >) {
415
431
val e = assertFailsWith<ExecutionException > { get() }
416
432
val cause = e.cause!!
You can’t perform that action at this time.
0 commit comments