You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Federico Mariani (Jira)" <ji...@apache.org> on 2026/07/16 13:21:00 UTC
[jira] [Updated] (CAMEL-24176) camel-cxfrs - async producer never maps HTTP errors to CxfOperationException (getClass().isInstance always false)
[ https://issues.apache.org/jira/browse/CAMEL-24176?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Federico Mariani updated CAMEL-24176:
-------------------------------------
Attachment: CxfRsProducerAsyncExceptionPredicateReproducerTest.java
> camel-cxfrs - async producer never maps HTTP errors to CxfOperationException (getClass().isInstance always false)
> -----------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-24176
> URL: https://issues.apache.org/jira/browse/CAMEL-24176
> Project: Camel
> Issue Type: Bug
> Components: camel-cxfrs
> Reporter: Federico Mariani
> Assignee: Federico Mariani
> Priority: Major
> Attachments: CxfRsProducerAsyncExceptionPredicateReproducerTest.java
>
>
> *Severity:* High *[reproducer attached]*
> h3. Problem
> In the asynchronous cxfrs producer callbacks {{CxfInvocationCallback.fail(..)}} and {{CxfProxyInvocationCallback.fail(..)}} the check for a JAX-RS error response is:
> {code:java}
> if (throwable.getClass().isInstance(WebApplicationException.class)) {
> ...
> } else if (throwable.getClass().isInstance(ResponseProcessingException.class)) {
> ...
> } else {
> exchange.setException(throwable);
> }
> {code}
> {{x.getClass().isInstance(y)}} tests whether the *argument* {{y}} is an instance of {{x}}'s class. Here the argument is the {{Class}} object {{WebApplicationException.class}} (a {{java.lang.Class}}), which is never an instance of any {{Throwable}}. *Both branches are dead code* and every async failure falls through to {{exchange.setException(throwable)}} with the raw JAX-RS exception.
> h3. Impact
> With the default {{synchronous=false}}, a server error (404/500...) yields the raw {{NotFoundException}}/{{InternalServerErrorException}} instead of the {{CxfOperationException}} (carrying status code, response headers and body) that the *synchronous* path produces via {{populateCxfRsProducerException}}. Any {{onException(CxfOperationException.class)}} handler that works with {{synchronous=true}} silently stops matching when the route runs async.
> h3. Location
> {{components/camel-cxf/camel-cxf-rest/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducer.java}} lines ~751, 757 ({{CxfInvocationCallback}}) and ~844, 850 ({{CxfProxyInvocationCallback}}).
> h3. Fix
> Use {{instanceof}}:
> {code:java}
> if (throwable instanceof WebApplicationException wae) {
> if (shouldHandleError(wae.getResponse())) { handleError(wae.getResponse()); }
> else { exchange.setException(throwable); }
> } else if (throwable instanceof ResponseProcessingException rpe) {
> ...
> } else {
> exchange.setException(throwable);
> }
> {code}
> Ensure the fixed branch still falls back to {{exchange.setException(throwable)}} when {{shouldHandleError}} returns false, so a non-handled exception isn't dropped. The two {{InvocationCallback}} inner classes duplicate this logic verbatim - de-duplicate them so the fix cannot regress in one copy.
> h3. Reproducer
> {{CxfRsProducerAsyncExceptionPredicateReproducerTest}} (attached) pins the defective predicate against a real {{WebApplicationException}} subclass and fails on current {{main}}.
> ----
> _Filed by Claude Code (Claude Fable) on behalf of Federico Mariani (GitHub: Croway). Findings from an AI-assisted code review of the camel-cxf component family; each item was verified against the current source and git history. Items marked *[reproducer attached]* include a failing JUnit test that demonstrates the defect._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)