-
Notifications
You must be signed in to change notification settings - Fork 30
Description
Description
Since vert.x 4.3 the order in which routes are registered is checked by io.vertx.ext.web.impl.RouteState
.
Using rest.vertx
with vert.x 4.3 can lead to an error in specific circumstances:
Exception in thread "main" java.lang.IllegalStateException: Cannot add [BODY] handler to route with [USER] handler at index 0
at io.vertx.ext.web.impl.RouteState.addContextHandler(RouteState.java:554)
at io.vertx.ext.web.impl.RouteImpl.handler(RouteImpl.java:143)
at com.zandero.rest.RestRouter.register(RestRouter.java:152)
at com.zandero.rest.RestRouter.register(RestRouter.java:70)
at com.zandero.rest.RestBuilder.getRouter(RestBuilder.java:497)
at com.zandero.rest.RestBuilder.build(RestBuilder.java:570)
This can be circumvented by setting the io.vertx.web.router.setup.lenient
property to true
, but even then a WARNING
is logged.
As far as I could tell, this issue occurs
- When the request body is present in the function parameters
- When context (e.g.
User
) is present in the function parameters
Resolution suggestions
From a cursory glance, the "weight" of a handler is determined by its type. As such, a PlatformHandler
should have the highest "priority". So a possible solution would be to mark the custom handlers that are registered before the body handler as implements io.vertx.ext.web.handler.PlatformHandler
.
If no marker interface is implemented, priority "USER" is assumed (lowest priority -> register last).
Steps to reproduce
Setup minimal vert.x app with a sample resource
fun main() {
val vertx = Vertx.vertx()
val router = RestBuilder(vertx)
.register(TestResource::class.java)
.build()
vertx.createHttpServer().requestHandler(router).listen(8080)
}
@Path("/test")
class TestResource {
@POST
fun postFoo(requestBody: String) = requestBody
@GET
fun getFoo(@Context user: User?) = "${user?.subject()}"
}
Use vert.x 4.3+ and rest.vertx 1.1
dependencies {
implementation(platform("io.vertx:vertx-stack-depchain:4.3.3"))
implementation("io.vertx:vertx-web")
implementation("com.zandero:rest.vertx:1.1")
}
Run app:
Exception in thread "main" java.lang.IllegalStateException: Cannot add [BODY] handler to route with [USER] handler at index 0
at io.vertx.ext.web.impl.RouteState.addContextHandler(RouteState.java:554)
at io.vertx.ext.web.impl.RouteImpl.handler(RouteImpl.java:143)
at com.zandero.rest.RestRouter.register(RestRouter.java:152)
at com.zandero.rest.RestRouter.register(RestRouter.java:70)
at com.zandero.rest.RestBuilder.getRouter(RestBuilder.java:497)
at com.zandero.rest.RestBuilder.build(RestBuilder.java:570)
at rest.vertx.repro.AppKt.main(App.kt:10)
at rest.vertx.repro.AppKt.main(App.kt)