-
Notifications
You must be signed in to change notification settings - Fork 1.9k
CompletionStage<T>.asDeferred() does not unwrap CompletionException #1479
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The wrapping is part of Invariant: that the following code throws
Note, that implementation of |
What about the following confusing behaviour? @Test
fun futureVsDeferredTest() {
val f1 = CompletableFuture<Int>()
val f2 = CompletableFuture<Int>()
val f = CompletableFuture.allOf(f1, f2).thenApply { f1.get() + f2.get() }
val d = f.asDeferred()
f1.completeExceptionally(TestException())
f2.complete(42)
runBlocking {
expectException<TestException> { f.await() }
expectException<TestException> { d.await() } // fails
}
} Moreover, if deferred is created from completed future, then test will pass. @Test
fun futureVsDeferredTest() {
val f1 = CompletableFuture<Int>()
val f2 = CompletableFuture<Int>()
val f = CompletableFuture.allOf(f1, f2).thenApply { f1.get() + f2.get() }
f1.completeExceptionally(TestException())
f2.complete(42)
val d = f.asDeferred()
runBlocking {
expectException<TestException> { f.await() }
expectException<TestException> { d.await() } // ok
}
} |
@arkrost I see the problem. Thanks a lot for a simple demo. The implementation of |
* A dedicated test is added that checks consistency of unwrapping between slow and fast paths of both CompletionStage.await and CompletionStage.asDeferred implementations. * In the fast-path for both of them implementation of CompletableFuture.get() does unwrapping of CompletionException, taking its cause when it is not null. To mimic this behavior, the slow path of both await and asDeferred shall perform similar unwrapping. Fixes #1479
* A dedicated test is added that checks consistency of unwrapping between slow and fast paths of both CompletionStage.await and CompletionStage.asDeferred implementations. * In the fast-path for both of them implementation of CompletableFuture.get() does unwrapping of CompletionException, taking its cause when it is not null. To mimic this behavior, the slow path of both await and asDeferred shall perform similar unwrapping. Fixes #1479
Hi,
Why does not
CompletionStage<T>.asDeferred()
unwrap CompletionException inwhenComplete
block? I mean why notresult.completeExceptionally((exception as? CompletionException)?.cause ?: exception)
in line Future.kt#L129.It would change the behaviour of the test testCompletableFutureWithExceptionAsDeferred to the following one
It seems more relevant IMO.
The text was updated successfully, but these errors were encountered: