question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

@ConsumeEvent can return `Uni<R>` if parameter is `T` but throws error for `Message<T>`

See original GitHub issue

Describe the bug

The “Using the event bus” documentation has examples of methods annotated with @ConsumesEvent returning void, R, and Uni<R>:

@ConsumeEvent("greeting")
public String consume(String name) {
    return name.toUpperCase();
}

@ConsumeEvent("greeting")
public Uni<String> consume2(String name) {
    return Uni.createFrom().item(() -> name.toUpperCase()).emitOn(executor);
}

Based on the examples I’d expect the same to work for Message<T>, but attempting to consume an event from EventBus.send or EventBus.request results in a NoSuchMethodError.

This occurs with both Kotlin and Java.

Expected behavior

A method annotated with @ConsumesEvent can return either void or Uni<R> regardless of whether the parameter is T or Message<T>.

Actual behavior

If the method parameter is Message<T>, the Vertx event bus only works if the return type is void.

2021-11-22 11:16:11,566 ERROR [io.qua.ver.cor.run.VertxCoreRecorder] (vert.x-eventloop-thread-2) Uncaught exception received by Vert.x: java.lang.NoSuchMethodError: 'void org.acme.Example.onMessageUni(io.vertx.core.eventbus.Message)'
        at org.acme.Example_VertxInvoker_onMessage_a71f19d99a55f26778e6ec15e5768a5d955c7f96.invokeBean(WebhookImportService_VertxInvoker_onMessageUni_a71f19d99a55f26778e6ec15e5768a5d955c7f96.zig:68)
        at io.quarkus.vertx.runtime.EventConsumerInvoker.invoke(EventConsumerInvoker.java:28)
        at io.quarkus.vertx.runtime.VertxRecorder$3$1.handle(VertxRecorder.java:118)
        at io.quarkus.vertx.runtime.VertxRecorder$3$1.handle(VertxRecorder.java:95)
        at io.vertx.core.impl.EventLoopContext.emit(EventLoopContext.java:50)
        at io.vertx.core.impl.DuplicatedContext.emit(DuplicatedContext.java:168)
        at io.vertx.core.eventbus.impl.MessageConsumerImpl.dispatch(MessageConsumerImpl.java:177)
        at io.vertx.core.eventbus.impl.HandlerRegistration$InboundDeliveryContext.next(HandlerRegistration.java:169)
        at io.vertx.core.eventbus.impl.HandlerRegistration$InboundDeliveryContext.dispatch(HandlerRegistration.java:134)
        at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:111)
        at io.vertx.core.eventbus.impl.HandlerRegistration.dispatch(HandlerRegistration.java:105)
        at io.vertx.core.eventbus.impl.MessageConsumerImpl.deliver(MessageConsumerImpl.java:183)
        at io.vertx.core.eventbus.impl.MessageConsumerImpl.doReceive(MessageConsumerImpl.java:168)
        at io.vertx.core.eventbus.impl.HandlerRegistration.lambda$receive$0(HandlerRegistration.java:56)
        at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
        at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base/java.lang.Thread.run(Thread.java:829)

How to Reproduce?

Code

@ConsumeEvent("json")
fun onJsonObject(json: JsonObject) {
    println("[Void] Received JsonObject: ${json.encode()}")
}

@ConsumeEvent("jsonUni")
fun onJsonObjectUni(json: JsonObject): Uni<String> {
    println("[Uni] Received JsonObject: ${json.encode()}")
    return Uni.createFrom().item("JsonObject")
}

@ConsumeEvent("message")
fun onMessage(message: Message<JsonObject>) {
    println("[Void] Received message: [headers=${message.headers()}, body=${message.body().encode()}]")
}

@ConsumeEvent("messageUni")
fun onMessageUni(message: Message<JsonObject>): Uni<String> {
    println("[Uni] Received message: [headers=${message.headers()}, body=${message.body().encode()}]")
    return Uni.createFrom().item("Message")
}

// Elsewhere in the code
val json = JsonObject().put("name", "quarkus")
val options = DeliveryOptions().addHeader("version", "2.5.0.CR1")
bus.send("json", json)
bus.request<String>("jsonUni", json).awaitSuspending()
bus.send("message", json, options)
bus.request<String>("messageUni", json, options).awaitSuspending()

Output

2021-11-22 11:54:28,308 ERROR [io.qua.ver.cor.run.VertxCoreRecorder] (vert.x-eventloop-thread-6) Uncaught exception received by Vert.x: java.lang.NoSuchMethodError: 'void org.acme.Example.onMessageUni(io.vertx.core.eventbus.Message)'
        at org.acme.Example_VertxInvoker_onMessageUni_17549bde5566bd9bd4470ce93824889fee55004c.invokeBean(WebhookImportService_VertxInvoker_onMessageUni_17549bde5566bd9bd4470ce93824889fee55004c.zig:68)
... (rest of the stacktrace)
[Uni] Received JsonObject: {"name":"quarkus"}
[Void] Received message: [headers=version=2.5.0.CR1, body={"name":"quarkus"}]
[Void] Received JsonObject: {"name":"quarkus"}

Output of uname -a or ver

No response

Output of java -version

No response

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.5.0.CR1

Build tool (ie. output of mvnw --version or gradlew --version)

No response

Additional information

No response

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:7 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
rgmzcommented, Nov 23, 2021

I’ve created PR #21653 to do 2. It likely needs some polishing, but let me know your thoughts on the general approach.

0reactions
cescoffiercommented, Nov 23, 2021

About 1 - well, @mkouba is fast! About 2 - yes, we could inject the message header as parameter.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Javascript function should throw an error if called without ...
Implement the ensure function so that it throws an error if called without arguments or an argument is undefined. Otherwise it should return...
Read more >
Vertx ConsumeEvent method handle exception #2164 - GitHub
If @ConsumeEvent method raise exception, it should be reply fail message to caller! Modified Class: io.quarkus.vertx.runtime.
Read more >
8 Conditions | Advanced R - Hadley Wickham
Write a wrapper around file.remove() that throws an error if the file to be deleted does not exist. What does the appendLF argument...
Read more >
OCaml for the Skeptical: Exception Handling - UChicago Library
Exceptions can (optionally) take a parameter, so that they can carry a value with them that can be extracted and examined if the...
Read more >
Arma 3: Writing a Function - Bohemia Interactive Community
1 Header; 2 Taking Arguments; 3 Returning Value; 4 Showing Errors ... When some values are incorrect, it should throw an error explaining ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found