shashank created CAMEL-25249:
--------------------------------
Summary: camel-vertx - a request/reply over the event bus gets a
successful reply (usually its own request) when the consumer route fails, and
no reply at all when the route ends without a body
Key: CAMEL-25249
URL: https://issues.apache.org/jira/browse/CAMEL-25249
Project: Camel
Issue Type: Bug
Components: camel-vertx
Reporter: shashank
{{VertxConsumer}} handles an event bus message that expects a reply
({{replyAddress() != null}}) as an {{InOut}} exchange and, when the exchange is
done, does:
{code:java}
if (reply) {
Object body = exchange.getMessage().getBody();
if (body != null) {
event.reply(body);
}
}
{code}
Two consequences:
# *A failed route answers with a successful reply.* The exception of the
exchange is ignored, and the reply carries whatever the message body is at that
point; when the route fails before changing the body, the sender gets its own
request back as the answer. A Camel sender ({{to("vertx:address")}} with
{{InOut}}) sees no exception at all; a Vert.x verticle using
{{eventBus.request(...)}} gets a {{succeeded()}} result. Errors are silently
turned into wrong answers.
# *No body, no reply.* When the route ends with a {{null}} body, nothing is
sent and the sender waits until its reply timeout (30 seconds by default,
{{ReplyException(TIMEOUT)}}), although the route completed.
Vert.x has {{Message.fail(failureCode, message)}} for the first case (the
sender gets a {{ReplyException}} with {{ReplyFailure.RECIPIENT_FAILURE}}), and
a {{null}} body is a valid reply. The code has been like this since
request/reply support was added (CAMEL-7176, 2014); nothing in the history or
the docs says the failure case is intended.
h3. Reproduction
{code:java}
from("direct:fail").to("vertx:foo.fail");
from("vertx:foo.fail").throwException(new IllegalArgumentException("Forced"));
from("direct:empty").to("vertx:foo.empty");
from("vertx:foo.empty").setBody(constant(null));
{code}
{{template.request("direct:fail", ...)}} returns an exchange without exception
(the body is the request); {{template.request("direct:empty", ...)}} fails
after 30 seconds with {{(TIMEOUT,-1) Timed out after waiting 30000(ms) for a
reply}}. A unit test with both fails on main.
h3. Proposed fix
When the exchange failed, reply with {{event.fail(500, "Exchange processing
failed")}}: the exception of the route is not sent to the sender (the security
model's rule for consumers that reply, see {{muteException}} in
CAMEL-24476/24477/24478/25087), it stays with the route's error handler.
Otherwise always reply with the body, also when it is {{null}}. An exception
handled by {{onException(...).handled(true)}} is not an exchange failure, so
its response is replied as before. The camel-vertx suite passes (31 tests). The
behaviour seen by senders changes, so the change gets an upgrade guide note.
Affected: 4.14.x, 4.18.x and main (same code).
Duplicate check (2026-10-01): JIRA component camel-vertx (all 25 issues) and
text "vertx" with "reply": nothing about failed or empty replies (CAMEL-7176
added the feature). GitHub pull requests "vertx reply": none.
_Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)