Skip to content

Webflux fails to apply the rule for controller methods returning void to kotlin suspend functions returning Unit #27629

Closed
@rogeriomgatto

Description

@rogeriomgatto

Affects: 5.3.12

Webflux fails to apply the rule for controller methods returning void to suspend functions returning Unit. Code like the example below causes error messages in log: ERROR o.s.w.s.a.HttpWebHandlerAdapter - [882bce24-1] Error [java.lang.UnsupportedOperationException] for HTTP POST "/some/api/path", but ServerHttpResponse already committed (200 OK)

@PostMapping
suspend fun doSomething(response: ServerHttpResponse): Unit {
    // ...
    response.writeWith(/* ... */).awaitSingleOrNull()
}

Cause

InvocableHandlerMethod::invoke wraps coroutine results with either mono or flux using CoroutinesUtils.invokeSuspendingFunction, but getReturnType simply returns Void.class. This in turn causes reactiveAdapterRegistry.getAdapter to return null and isAsyncVoidReturnType to return false

Workaround

Remove suspend modifier and replicate CoroutinesUtils.invokeSuspendingFunction wrapping manually:

@PostMapping
fun doSomething(response: ServerHttpResponse) = mono(Dispatchers.Unconfined) {
    // ...
    response.writeWith(/* ... */).awaitSingleOrNull()
}
    .filter { false }
    .onErrorMap(InvocationTargetException::class.java, InvocationTargetException::getTargetException)
    .cast(Void.TYPE)

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)theme: kotlinAn issue related to Kotlin supporttype: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions