Skip to content

CAMEL-24176: camel-cxfrs - Fix async producer never mapping HTTP errors to CxfOperationException - #24924

Merged
davsclaus merged 1 commit into
mainfrom
fix/CAMEL-24176
Jul 20, 2026
Merged

CAMEL-24176: camel-cxfrs - Fix async producer never mapping HTTP errors to CxfOperationException#24924
davsclaus merged 1 commit into
mainfrom
fix/CAMEL-24176

Conversation

@davsclaus

Copy link
Copy Markdown
Contributor

Claude Code on behalf of davsclaus

Summary

Fix two bugs in the async CXF-RS producer's fail() callback in both CxfInvocationCallback and CxfProxyInvocationCallback:

  1. Reversed isInstance checkthrowable.getClass().isInstance(WebApplicationException.class) always evaluates to false because it tests whether the Class object is an instance of the throwable's class (which it never is). Both if branches were dead code, so every async failure fell through to exchange.setException(throwable) with the raw JAX-RS exception instead of wrapping it in CxfOperationException. Fixed by replacing with throwable instanceof WebApplicationException (same for ResponseProcessingException).

  2. Silent exception swallowing — When shouldHandleError() returned false (e.g., throwExceptionOnFailure=false or status ≤ 207), neither handleError() nor exchange.setException() was called — the exception was silently dropped. Added else { exchange.setException(throwable); } fallback in each branch.

Impact

With the default synchronous=false, a server error (404/500) now correctly yields a CxfOperationException (carrying status code, response headers and body) — matching the synchronous path behavior. onException(CxfOperationException.class) handlers now work consistently regardless of sync/async mode.

Test plan

  • Added testAsyncProxyProducerServerErrorMappedToCxfOperationException — calls via the proxy client API with an invalid ID that triggers a 500 on the server; verifies the exchange exception is CxfOperationException with status 500 (not a raw InternalServerErrorException)
  • All 18 existing CxfRsAsyncProducerTest tests pass

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

…rs to CxfOperationException

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
@github-actions

Copy link
Copy Markdown
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch — two real bugs fixed.

Bug 1: Reversed isInstancethrowable.getClass().isInstance(WebApplicationException.class) always returns false because it tests whether the Class<WebApplicationException> object is an instance of the throwable's runtime class (which it never is — Class is not an exception). This made both if/else if branches dead code, so every async WebApplicationException and ResponseProcessingException fell through to the raw exchange.setException(throwable) path, bypassing CxfOperationException wrapping entirely. The fix correctly uses instanceof with pattern matching.

Bug 2: Silent exception swallowing — When shouldHandleError() returned false (e.g., throwExceptionOnFailure=false or status ≤ 207), neither handleError() nor exchange.setException() was called — the failure was silently dropped. The added else { exchange.setException(throwable); } ensures the exception always reaches the exchange.

Code quality: Modern instanceof pattern matching replaces verbose .getClass().isInstance() + .class.cast() — cleaner and correct. Fix correctly applied to both CxfInvocationCallback and CxfProxyInvocationCallback.

Test: Well-structured — sends an invalid ID that triggers a server-side 500, then asserts the async proxy producer properly maps the WebApplicationException to CxfOperationException with the correct status code.

LGTM ✅

Claude Code on behalf of gnodet — AI-generated review

@github-actions

Copy link
Copy Markdown
Contributor

🧪 CI tested the following changed modules:

  • components/camel-cxf/camel-cxf-rest
  • components/camel-cxf/camel-cxf-spring-rest

🔬 Scalpel shadow comparison — Scalpel: 16 tested, 29 compile-only — current: 16 all tested

Maveniverse Scalpel detected 45 affected modules (current approach: 16).

⚠️ Modules only in Scalpel (29)
  • apache-camel
  • camel-allcomponents
  • camel-catalog
  • camel-catalog-console
  • camel-catalog-lucene
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-csimple-maven-plugin
  • camel-endpointdsl
  • camel-endpointdsl-support
  • camel-itest
  • camel-jbang-core
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-kamelet-main
  • camel-launcher
  • camel-report-maven-plugin
  • camel-route-parser
  • camel-yaml-dsl
  • camel-yaml-dsl-deserializers
  • camel-yaml-dsl-maven-plugin
  • coverage
  • docs
  • dummy-component

Skip-tests mode would test 16 modules (2 direct + 14 downstream), skip tests for 29 (generated code, meta-modules)

Modules Scalpel would test (16)
  • camel-cxf-rest
  • camel-cxf-spring-rest
  • camel-jbang-mcp
  • camel-jbang-plugin-mcp
  • camel-jbang-plugin-route-parser
  • camel-jbang-plugin-tui
  • camel-jbang-plugin-validate
  • camel-launcher-container
  • camel-micrometer-observability
  • camel-observability-services
  • camel-opentelemetry
  • camel-opentelemetry2
  • camel-telemetry
  • camel-telemetry-dev
  • camel-yaml-dsl-validator
  • camel-yaml-dsl-validator-maven-plugin
Modules with tests skipped (29)
  • apache-camel
  • camel-allcomponents
  • camel-catalog
  • camel-catalog-console
  • camel-catalog-lucene
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-csimple-maven-plugin
  • camel-endpointdsl
  • camel-endpointdsl-support
  • camel-itest
  • camel-jbang-core
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-kamelet-main
  • camel-launcher
  • camel-report-maven-plugin
  • camel-route-parser
  • camel-yaml-dsl
  • camel-yaml-dsl-deserializers
  • camel-yaml-dsl-maven-plugin
  • coverage
  • docs
  • dummy-component

ℹ️ Shadow mode — Scalpel observes but does not affect test execution. Learn more

All tested modules (45 modules)
  • Camel :: All Components Sync point
  • Camel :: Assembly
  • Camel :: CXF :: REST
  • Camel :: CXF :: REST :: Spring
  • Camel :: Catalog :: CSimple Maven Plugin (deprecated)
  • Camel :: Catalog :: Camel Catalog
  • Camel :: Catalog :: Camel Report Maven Plugin
  • Camel :: Catalog :: Camel Route Parser
  • Camel :: Catalog :: Console
  • Camel :: Catalog :: Dummy Component
  • Camel :: Catalog :: Lucene (deprecated)
  • Camel :: Catalog :: Maven
  • Camel :: Catalog :: Suggest
  • Camel :: Common Telemetry
  • Camel :: Component DSL
  • Camel :: Coverage
  • Camel :: Docs
  • Camel :: Endpoint DSL
  • Camel :: Endpoint DSL :: Support
  • Camel :: Integration Tests
  • Camel :: JBang :: Core
  • Camel :: JBang :: Integration tests
  • Camel :: JBang :: MCP
  • Camel :: JBang :: Main
  • Camel :: JBang :: Plugin :: Edit
  • Camel :: JBang :: Plugin :: Generate
  • Camel :: JBang :: Plugin :: Kubernetes
  • Camel :: JBang :: Plugin :: MCP
  • Camel :: JBang :: Plugin :: Route Parser
  • Camel :: JBang :: Plugin :: TUI
  • Camel :: JBang :: Plugin :: Testing
  • Camel :: JBang :: Plugin :: Validate
  • Camel :: Kamelet Main
  • Camel :: Launcher
  • Camel :: Launcher :: Container
  • Camel :: Micrometer :: Observability 2
  • Camel :: Observability Services
  • Camel :: OpenTelemetry (deprecated)
  • Camel :: Opentelemetry 2
  • Camel :: Telemetry :: Dev
  • Camel :: YAML DSL
  • Camel :: YAML DSL :: Deserializers
  • Camel :: YAML DSL :: Maven Plugins
  • Camel :: YAML DSL :: Validator
  • Camel :: YAML DSL :: Validator Maven Plugin

⚙️ View full build and test results

@davsclaus davsclaus added this to the 4.22.0 milestone Jul 20, 2026
@davsclaus davsclaus added the bug Something isn't working label Jul 20, 2026
@davsclaus davsclaus self-assigned this Jul 20, 2026
@davsclaus
davsclaus merged commit 2fd62dd into main Jul 20, 2026
5 checks passed
@davsclaus
davsclaus deleted the fix/CAMEL-24176 branch July 20, 2026 09:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants