Claus Ibsen created CAMEL-26136:
-----------------------------------
Summary: camel-netty - with the default codec a failed exchange or
a non-String reply sends no reply and the client waits, and useByteBuf=true
skips a File, Map or POJO body silently
Key: CAMEL-26136
URL: https://issues.apache.org/jira/browse/CAMEL-26136
Project: Camel
Issue Type: Bug
Components: camel-netty
Reporter: Claus Ibsen
Fix For: 4.24.0
Found while adding the catalog body types of netty (CAMEL-24961, PR #28395).
h4. 1. A failed exchange gets no reply with the default codec
When the exchange fails, {{ServerChannelHandler.getResponseBody}} (main
2a465aa4814c, line 224) returns the muted stand-in {{Exception}} (added by
CAMEL-25902) or the route's exception as the reply. With the default codec (no
{{textline}}, {{allowDefaultCodec=true}}) the only encoder is the String
encoder, which cannot write an {{Exception}}, so the write fails,
{{ServerResponseFutureListener}} (line 51) only logs it, and the client gets
nothing: the producer fails with {{ReadTimeoutException}}. With
{{textline=true}} the error is converted to a String and replied. Checked on
4.24.0-SNAPSHOT with real TCP sockets.
Proposed: convert the exception reply to a String (as textline does) when the
String codec is in use, or close the channel so the client does not wait.
h4. 2. A reply that is not a String is dropped and the client waits
With the default codec a reply of bytes, a stream, a file, a Map or a POJO is
passed to the String encoder in {{ServerChannelHandler.sendResponse}} (line
182), which does not encode it; the write fails and
{{ServerResponseFutureListener}} (line 51) logs a WARN. The channel stays open
and the client waits for a reply, forever when {{requestTimeout}} is not set.
Checked on 4.24.0-SNAPSHOT with real TCP sockets.
Proposed: convert the reply to a String (the codec's type) before writing, and
fail with a clear error when it cannot be converted, closing the channel.
h4. 3. With useByteBuf=true a File, Map or POJO body is skipped silently
{{NettyPayloadHelper.getIn}} (line 46) uses the non-mandatory
{{getBody(ByteBuf.class)}}, which gives null for a File, a Map or a POJO.
{{NettyProducer.process}} (line 232) then logs "No payload to send" and
completes the exchange without error, so nothing is sent; the same helper is
used for the consumer reply (ServerChannelHandler line 230). Checked on
4.24.0-SNAPSHOT with real TCP sockets.
Proposed: use {{getMandatoryBody(ByteBuf.class)}} so a body that cannot be
converted fails the exchange.
h4. 4. With sync=false the producer still sets the server's reply on the
exchange
With {{sync=false}} {{NettyProducer}} (line 391) calls the callback as soon as
the request is written, but {{ClientChannelHandler.channelRead0}} (line 189)
still sets a reply that arrives later as the out (or in) message of the same
exchange, while the route has already moved on with it. The body seen after the
producer depends on timing. Checked on 4.24.0-SNAPSHOT with real TCP sockets.
Proposed: ignore (or log) messages received in {{ClientChannelHandler}} when
{{sync=false}}.
_Claude Code on behalf of davsclaus_
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)