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)

Reply via email to