[ 
https://issues.apache.org/jira/browse/CAMEL-25247?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Claus Ibsen updated CAMEL-25247:
--------------------------------
    Fix Version/s: 4.23.0

> camel-thrift - the consumer does not send a route failure to the client: the 
> synchronous server ignores it, the asynchronous server writes both the error 
> and a response, so the error answers the next call on the connection
> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25247
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25247
>             Project: Camel
>          Issue Type: Bug
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>             Fix For: 4.23.0
>
>
> {{ThriftMethodHandler}} turns a Thrift call into an exchange. It does not 
> handle a failed exchange correctly in either server mode:
> # *Asynchronous server (the default, {{THsHaServer}}).* The completion 
> callback does
> {code:java}
> if (exception != null) {
>     callback.onError(exception);
> }
> message = exchange.getMessage();
> ...
> callback.onComplete(response);
> {code}
> so for a failed exchange it calls {{onError}} *and then* {{onComplete}}. For 
> a {{void}} method, and for any method whose generated {{onComplete}} can 
> write a result (an object return type such as a struct or a string, or a body 
> of the failed exchange that converts to the return type), two results are 
> written for one call. With a framed client on one connection, a failing 
> {{void ping()}} returns normally, and the {{TApplicationException}} meant for 
> it is read as the answer to the *next* call ({{add(12, 13)}} fails with 
> "Forced"); every later answer on that connection is shifted by one. (For a 
> method returning a primitive whose failed body converts to {{null}}, the 
> generated {{onComplete}} fails on unboxing before it writes, so only the 
> error is sent: that is why the asynchronous {{calculate}} case below passes 
> on main.)
> # *Synchronous server ({{synchronous=true}}).* After 
> {{consumer.getProcessor().process(exchange)}} the exception of the exchange 
> is never looked at: a {{void}} method returns normally (the client sees 
> success), any other method returns the body of the failed exchange converted 
> to its return type, or fails with {{TApplicationException: Return type 
> requires not empty body}} when it does not convert, and an exception declared 
> by the IDL ({{throws (1:InvalidOperation ouch)}}) thrown by the route never 
> reaches the client as such.
> The code has been like this since the component was added (CAMEL-11333, 2017).
> h3. Reproduction
> Routes for the test {{Calculator}} service ({{add}} answers 25, {{calculate}} 
> throws {{new InvalidOperation(1, "Forced")}}, other methods throw 
> {{IllegalStateException("Forced")}}), one with {{synchronous=true}} and one 
> with the default asynchronous server, and a {{Calculator.Client}} over 
> {{TFramedTransport}}:
> * synchronous: {{calculate}} fails with {{TApplicationException}} instead of 
> {{InvalidOperation}}; {{ping}} returns normally;
> * asynchronous: {{ping}} returns normally and the following {{add(12, 13)}} 
> on the same connection throws {{TApplicationException: Forced}}.
> The test fails on main for these three cases (the asynchronous {{calculate}} 
> case passes on main, see above).
> h3. Proposed fix
> * synchronous handler: throw the exception of the exchange, so the Thrift 
> processor writes a declared exception as such and any other one as 
> {{TApplicationException}};
> * asynchronous handler: complete the call exactly once, with 
> {{onError(exception)}} when the exchange failed, otherwise with 
> {{onComplete(response)}}; the "unable to detect the return type" and "null 
> message" errors also return instead of falling through to {{onComplete}}.
> With the fix the new test ({{ThriftConsumerExceptionTest}}, 4 tests) and the 
> whole camel-thrift suite (45 tests) pass. Clients now get errors for failed 
> exchanges, 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 text "thrift" (26 issues; no component 
> filter matches) : nothing about exceptions or failed exchanges in the 
> consumer (CAMEL-24442 is the data format, CAMEL-16133 multiplexing). GitHub 
> pull requests "thrift": none about it.
> _Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to