Skip to content

web.reactive.function.server.ServerRequest.awaitBody() exception handling #30926

@GeorgePap-719

Description

@GeorgePap-719

Affects: Spring v6.0.6

What is the recommended approach on handling ServerRequest.awaitBody()

Right now, the API is using under the hood awaitSingle() from kotlinx.coroutines.reactive, which is intentional from
the spring team. Now, the API is throwing either NoSuchElementException or IllegalArgmuentException depending on if
the publisher emits zero or more than one values.

Question: In general code, are we expected to catch them both? Although, the operator is being used on a Mono,
which technically can never throw IllegalArgmuentException?

On the other hand, since we always extract the body (thus we are not directly affected by how a client writes in body)
in either a Flux or Mono if the client emits more than one values, but we use ServerRequest.awaitBody() the body
is converted properly, and we are retrieving a collection. Though, this process breaks in serialization
(as expected).

Usage in general code

The most "blur" part is about throwing IllegalArgmuentException. That is because, when using kotlinx.serialization
for general "catch-all" around deserialization it is recommended to catch IllegalArgmuentException. In that case, we
have to know beforehand if we need to also check if IllegalArgmuentException is type of SerializationException
(so we can distinguish between them).

When I am writing code to handle ServerRequest.awaitBody(), I find it a one-way path to use
ServerRequest.awaitBodyOrNull() API to avoid all the above points.

My exception handling looks like this:

suspend inline fun <reified T : Any> ServerRequest.awaitAndRequireBody(): T {
    val body = try {
        awaitBodyOrNull<T>()
    } catch (e: IllegalArgumentException) { // serialization error
        throw IllegalArgumentException(bodyTypeErrorMessage<T>())
    }
    requireNotNull(body) { bodyTypeErrorMessage<T>() }
    return body
}

Which makes ServerRequest.awaitBody() kind of "obsolete" API (at least imho).

Proposal

I recommend to at least document about the fact that ServerRequest.awaitBody() throws exceptions which are expected to be caught from the user.

Also, happy to provide a pr with the changes.

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)status: declinedA suggestion or change that we don't feel we should currently applytheme: kotlinAn issue related to Kotlin support

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions