This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 131964a398da CAMEL-22874: camel-openapi-rest - Fix issue with error
handler invoked twice when using handled(false) for rest-dsl with openapi
contract-first
131964a398da is described below
commit 131964a398da672bf4b744d0c5fbfc310e2e5a64
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Feb 7 11:40:17 2026 +0100
CAMEL-22874: camel-openapi-rest - Fix issue with error handler invoked
twice when using handled(false) for rest-dsl with openapi contract-first
---
... RestOpenApiCodeFirstOnExceptionIssueTest.java} | 27 ++++++++++++++++++----
...tOpenApiContractFirstOnExceptionIssueTest.java} | 19 +++++++++++----
.../apache/camel/model/rest/RestDefinition.java | 3 +++
3 files changed, 39 insertions(+), 10 deletions(-)
diff --git
a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/RestOpenApiOnExceptionIssueTest.java
b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/RestOpenApiCodeFirstOnExceptionIssueTest.java
similarity index 82%
copy from
components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/RestOpenApiOnExceptionIssueTest.java
copy to
components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/RestOpenApiCodeFirstOnExceptionIssueTest.java
index ac0bc327aed3..12976aa29846 100644
---
a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/RestOpenApiOnExceptionIssueTest.java
+++
b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/RestOpenApiCodeFirstOnExceptionIssueTest.java
@@ -23,12 +23,16 @@ import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.test.AvailablePortFinder;
import org.apache.camel.test.junit5.CamelTestSupport;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
-public class RestOpenApiOnExceptionIssueTest extends CamelTestSupport {
+public class RestOpenApiCodeFirstOnExceptionIssueTest extends CamelTestSupport
{
+
+ @Override
+ protected boolean useJmx() {
+ return true;
+ }
@Test
public void testOnExceptionHandledTrue() throws Exception {
@@ -37,10 +41,17 @@ public class RestOpenApiOnExceptionIssueTest extends
CamelTestSupport {
public void configure() throws Exception {
onException(Exception.class)
.log("Error processing request: ${exception.message}")
+ .process(e -> {
+ log.info("onException: {}", e);
+ })
.to("mock:error")
.handled(true);
-
rest().openApi().specification("openapi-v3.json").missingOperation("ignore");
+ restConfiguration().contextPath("/api/v3");
+
+ rest()
+ .get("pet/{id}")
+ .to("direct:getPetById");
from("direct:getPetById").routeId("directRoute")
.process(e -> {
@@ -61,17 +72,23 @@ public class RestOpenApiOnExceptionIssueTest extends
CamelTestSupport {
}
@Test
- @Disabled
public void testOnExceptionHandledFalse() throws Exception {
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
onException(Exception.class)
.log("Error processing request: ${exception.message}")
+ .process(e -> {
+ log.info("onException: {}", e);
+ })
.to("mock:error")
.handled(false);
-
rest().openApi().specification("openapi-v3.json").missingOperation("ignore");
+ restConfiguration().contextPath("/api/v3");
+
+ rest()
+ .get("pet/{id}")
+ .to("direct:getPetById");
from("direct:getPetById").routeId("directRoute")
.process(e -> {
diff --git
a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/RestOpenApiOnExceptionIssueTest.java
b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/RestOpenApiContractFirstOnExceptionIssueTest.java
similarity index 87%
rename from
components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/RestOpenApiOnExceptionIssueTest.java
rename to
components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/RestOpenApiContractFirstOnExceptionIssueTest.java
index ac0bc327aed3..97908f46dd71 100644
---
a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/RestOpenApiOnExceptionIssueTest.java
+++
b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/RestOpenApiContractFirstOnExceptionIssueTest.java
@@ -23,12 +23,16 @@ import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.test.AvailablePortFinder;
import org.apache.camel.test.junit5.CamelTestSupport;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
-public class RestOpenApiOnExceptionIssueTest extends CamelTestSupport {
+public class RestOpenApiContractFirstOnExceptionIssueTest extends
CamelTestSupport {
+
+ @Override
+ protected boolean useJmx() {
+ return true;
+ }
@Test
public void testOnExceptionHandledTrue() throws Exception {
@@ -37,10 +41,13 @@ public class RestOpenApiOnExceptionIssueTest extends
CamelTestSupport {
public void configure() throws Exception {
onException(Exception.class)
.log("Error processing request: ${exception.message}")
+ .process(e -> {
+ log.info("onException: {}", e);
+ })
.to("mock:error")
.handled(true);
-
rest().openApi().specification("openapi-v3.json").missingOperation("ignore");
+
rest().openApi().specification("openapi-v3.json").missingOperation("ignore").routeId("petStore");
from("direct:getPetById").routeId("directRoute")
.process(e -> {
@@ -61,17 +68,19 @@ public class RestOpenApiOnExceptionIssueTest extends
CamelTestSupport {
}
@Test
- @Disabled
public void testOnExceptionHandledFalse() throws Exception {
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
onException(Exception.class)
.log("Error processing request: ${exception.message}")
+ .process(e -> {
+ log.info("onException: {}", e);
+ })
.to("mock:error")
.handled(false);
-
rest().openApi().specification("openapi-v3.json").missingOperation("ignore");
+
rest().openApi().specification("openapi-v3.json").missingOperation("ignore").routeId("petStore");
from("direct:getPetById").routeId("directRoute")
.process(e -> {
diff --git
a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
index ee8e1d7bc827..62fb3354f156 100644
---
a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
+++
b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
@@ -41,6 +41,7 @@ import org.apache.camel.model.OptionalIdentifiedDefinition;
import org.apache.camel.model.RouteDefinition;
import org.apache.camel.model.StopDefinition;
import org.apache.camel.model.ToDefinition;
+import org.apache.camel.model.errorhandler.NoErrorHandlerDefinition;
import org.apache.camel.spi.AsEndpointUri;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.NodeIdFactory;
@@ -1107,6 +1108,8 @@ public class RestDefinition extends
OptionalIdentifiedDefinition<RestDefinition>
// the route should be from this rest endpoint
route.fromRest(from);
+ // rest-dsl open-api contract-first is only a facade and each route
handles error handling
+ route.setErrorHandlerFactory(new NoErrorHandlerDefinition());
route.getInput().setLocation(getLocation());
route.getInput().setLineNumber(getLineNumber());
route.setRestDefinition(this);