Affected component: spring-webflux Version: 5.3.2
When using the Kotlin-Extensions for WebClient on Endpoints that do not return any data, awaitBody<Unit>
is throwing java.util.NoSuchElementException: No value received via onNext for awaitSingle
.
I was thinking I may accidentally misuse the API, but spring-docs document also this call:
val personDeferred: Deferred<Person> = ...
client.post()
.uri("/persons/{id}", id)
.contentType(MediaType.APPLICATION_JSON)
.body<Person>(personDeferred)
.retrieve()
.awaitBody<Unit>()
Reproduction: Given the following controller:
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.*
@RestController
class TestController {
@PostMapping("/test")
@ResponseStatus(HttpStatus.NO_CONTENT)
fun postTest() {}
}
And this Unit-Test:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
internal class TestControllerTest(
@LocalServerPort private val port : Int
) {
@Test
fun postTest() = runBlocking {
WebClient.create("localhost:$port/test")
.post()
.retrieve()
.awaitBody<Unit>()
}
}
The test will fail with
java.util.NoSuchElementException: No value received via onNext for awaitSingle
at |b|b|b(Coroutine boundary.|b(|b)
at TestControllerTest$deleteTest$1.invokeSuspend(TestControllerTest.kt:52)
Caused by: java.util.NoSuchElementException: No value received via onNext for awaitSingle
at kotlinx.coroutines.reactive.AwaitKt$awaitOne$$inlined$suspendCancellableCoroutine$lambda$1.onComplete(Await.kt:181)
at reactor.core.publisher.StrictSubscriber.onComplete(StrictSubscriber.java:123)
Comment From: blatobi
Current workaround:
WebClient.create("localhost:$port/test")
.post()
.retrieve()
.toBodilessEntity()
.awaitSingleOrNull()
Comment From: sdeleuze
You should probably use ClientResponse.awaitBodilessEntity()
for that use case, I will update the documentation accordingly.
Comment From: blatobi
2 thoughts:
* awaitBody<Unit>
still feels more accurate then 'toBodyless....
* Even with a changed documentation, shouldn't the extension-method throw
IllegalArgument, if the type
Unit` isn't valid?
Comment From: gaerfield
@sdeleuze I have created a pull-request with allowing awaitBody<Unit>()
and introduced also awaitBodilessEntity
like in ClientResponse.awaitBodilessEntity()
. Let me know what you think...
Comment From: rstoyanchev
Superseded by #26504.