[
https://issues.apache.org/jira/browse/CAMEL-25247?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen reassigned CAMEL-25247:
-----------------------------------
Assignee: shashank
> 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
>
> {{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)