File tree 2 files changed +30
-3
lines changed
kotlinx-coroutines-jdk8/src
main/kotlin/kotlinx/coroutines/experimental/future
test/kotlin/kotlinx/coroutines/experimental/future
2 files changed +30
-3
lines changed Original file line number Diff line number Diff line change @@ -50,9 +50,19 @@ public fun <T> Deferred<T>.toCompletableFuture(): CompletableFuture<T> {
50
50
* If the [Job] of the current coroutine is completed while this suspending function is waiting, this function
51
51
* immediately resumes with [CancellationException] .
52
52
*/
53
- public suspend fun <T > CompletableFuture<T>.await (): T =
54
- // quick check if already complete (avoid extra object creation)
55
- if (isDone) get() else suspendCancellableCoroutine { cont: CancellableContinuation <T > ->
53
+ public suspend fun <T > CompletableFuture<T>.await (): T {
54
+ if (isDone) {
55
+ // then only way to get unwrapped exception from the CompletableFuture...
56
+ var result: T ? = null
57
+ var exception: Throwable ? = null
58
+ whenComplete { r, e ->
59
+ result = r
60
+ exception = e
61
+ }
62
+ if (exception != null ) throw exception!!
63
+ return result as T
64
+ }
65
+ return suspendCancellableCoroutine { cont: CancellableContinuation <T > ->
56
66
val completionFuture = whenComplete { result, exception ->
57
67
if (exception == null ) // the future has been completed normally
58
68
cont.resume(result)
@@ -62,6 +72,7 @@ public suspend fun <T> CompletableFuture<T>.await(): T =
62
72
cont.cancelFutureOnCompletion(completionFuture)
63
73
Unit
64
74
}
75
+ }
65
76
66
77
private class CompletableFutureCoroutine <T >(
67
78
override val context : CoroutineContext
Original file line number Diff line number Diff line change @@ -37,6 +37,22 @@ class FutureTest {
37
37
assertEquals(" OK" , future.get())
38
38
}
39
39
40
+ @Test
41
+ fun testDoneFutureCompletedExceptionally () {
42
+ val toAwait = CompletableFuture <String >()
43
+ toAwait.completeExceptionally(RuntimeException (" O" ))
44
+ val future = future<String > {
45
+ try {
46
+ toAwait.await()
47
+ } catch (e: RuntimeException ) {
48
+ e.message!!
49
+ } + " K"
50
+ }
51
+
52
+ assertFalse(future.isDone)
53
+ assertEquals(" OK" , future.get())
54
+ }
55
+
40
56
@Test
41
57
fun testAwaitedFutureCompletedExceptionally () {
42
58
val toAwait = CompletableFuture <String >()
You can’t perform that action at this time.
0 commit comments