This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch feature/CAMEL-24237-catalog-docs
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 9ff8d69c0e37a20f4a5a5e12c2ccf1fa66e40c8a
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Jul 22 13:07:14 2026 +0200

    CAMEL-24237: Add doTry EIP documentation and skip when/otherwise from EIP 
list
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../org/apache/camel/catalog/docs.properties       |   1 +
 .../org/apache/camel/catalog/docs/doTry-eip.adoc   | 246 +++++++++++++++++++++
 .../main/docs/modules/eips/pages/doTry-eip.adoc    | 246 +++++++++++++++++++++
 .../dsl/jbang/core/commands/tui/CatalogTab.java    |   4 +
 4 files changed, 497 insertions(+)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs.properties
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs.properties
index 518dd4f70586..8b971e97b717 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs.properties
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs.properties
@@ -152,6 +152,7 @@ disruptor-component
 disruptor-vm-component
 djl-component
 dns-component
+doTry-eip
 docker-component
 docling-async-processing
 docling-batch-processing
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/doTry-eip.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/doTry-eip.adoc
new file mode 100644
index 000000000000..0b43a808862f
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/doTry-eip.adoc
@@ -0,0 +1,246 @@
+= Do Try EIP
+:doctitle: Do Try
+:shortname: doTry
+:description: Wraps route steps in a try-catch-finally block for fine-grained 
exception handling within the route
+:since: 
+:supportlevel: Stable
+:tabs-sync-option:
+
+Camel supports the Java equivalent of try, catch, and finally directly in the 
DSL.
+It aims to work like its Java sisters but with more power.
+
+In Camel, we prefix the keywords with `do` to avoid having same keyword as 
Java.
+So we have:
+
+- `doTry`
+- `doCatch`
+- `doFinally`
+- `end` to end the block in Java DSL
+
+[IMPORTANT]
+====
+When using `doTry ... doCatch ... doFinally`, the regular Camel
+xref:manual::error-handler.adoc[Error Handler] is not in use; meaning any
+`onException` or the likes does not trigger.
+
+The reason is that
+`doTry ... doCatch ... doFinally` is in fact its own error handler and mimics 
how try/catch/finally works in Java.
+====
+
+== EIP options
+
+// eip options: START
+include::partial$eip-options.adoc[]
+// eip options: END
+
+== Using doTry ... doCatch ... doFinally
+
+In the route below we have all of them in action:
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+from("direct:start")
+    .doTry()
+        .process(new ProcessorFail())
+        .to("mock:result")
+    .doCatch(IOException.class, IllegalStateException.class)
+        .to("mock:catch")
+    .doFinally()
+        .to("mock:finally")
+    .end();
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+  <from uri="direct:start"/>
+  <doTry>
+    <process ref="processorFail"/>
+    <to uri="mock:result"/>
+    <doCatch>
+      <exception>java.io.IOException</exception>
+      <exception>java.lang.IllegalStateException</exception>
+      <to uri="mock:catch"/>
+    </doCatch>
+    <doFinally>
+       <to uri="mock:finally"/>
+    </doFinally>
+  </doTry>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:start
+      steps:
+        - doTry:
+            steps:
+              - process:
+                  ref: processorFail
+              - to:
+                  uri: mock:result
+              - doCatch:
+                  exception:
+                    - java.io.IOException
+                    - java.lang.IllegalStateException
+                  steps:
+                    - to:
+                        uri: mock:catch
+              - doFinally:
+                  steps:
+                    - to:
+                        uri: mock:finally
+----
+====
+
+=== Using onWhen with doCatch
+
+You can use xref:manual::predicate.adoc[Predicates] with `doCatch` to make it 
determine at runtime if the block should be triggered or not.
+In this example, we only want to trigger if the caused exception message 
contains the word *Damn*.
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+from("direct:start")
+    .doTry()
+        .process(new ProcessorFail())
+        .to("mock:result")
+    .doCatch(IOException.class, IllegalStateException.class)
+        .onWhen(exceptionMessage().contains("Damn"))
+        .to("mock:catch")
+    .doCatch(CamelExchangeException.class)
+        .to("mock:catchCamel")
+    .doFinally()
+        .to("mock:finally")
+    .end();
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+  <from uri="direct:start"/>
+  <doTry>
+    <process ref="processorFail"/>
+    <to uri="mock:result"/>
+    <doCatch>
+      <exception>java.io.IOException</exception>
+      <exception>java.lang.IllegalStateException</exception>
+      <onWhen>
+        <simple>${exception.message} contains 'Damn'</simple>
+      </onWhen>
+      <to uri="mock:catch"/>
+    </doCatch>
+    <doCatch>
+      <exception>org.apache.camel.CamelExchangeException</exception>
+      <to uri="mock:catchCamel"/>
+    </doCatch>
+    <doFinally>
+       <to uri="mock:finally"/>
+    </doFinally>
+  </doTry>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:start
+      steps:
+        - doTry:
+            steps:
+              - process:
+                  ref: processorFail
+              - to:
+                  uri: mock:result
+              - doCatch:
+                  exception:
+                    - java.io.IOException
+                    - java.lang.IllegalStateException
+                  steps:
+                    - onWhen:
+                        expression:
+                          simple:
+                            expression: "${exception.message} contains 'Damn'"
+                    - to:
+                        uri: mock:catch
+              - doCatch:
+                  exception:
+                    - org.apache.camel.CamelExchangeException
+                  steps:
+                    - to:
+                        uri: mock:catchCamel
+              - doFinally:
+                  steps:
+                    - to:
+                        uri: mock:finally
+----
+====
+
+=== Use end() to end the block
+
+When using Java DSL you must use `end()` to indicate where the try ... catch 
... finally block ends.
+If the route has a `doFinally`, then the `end()` should be at the end of the 
finally block.
+If there is no `doFinally`, then the `end()` should be at the end of the last 
`doCatch`.
+
+TIP: Instead of `end()` you can use `endDoTry()` to end and _return back_ to 
the try ... catch scope.
+
+=== Nested doTry ... doCatch
+
+When nesting `doTry ... doCatch` from an outer `doTry ... doCatch` EIP,
+pay extra attention when using Java DSL as the Java programming language is 
not _indent aware_
+so you may write code that is indented in a way where you think a catch block 
is associated with the other doTry, but it is not.
+
+Given the following Java DSL:
+
+[source,java]
+----
+from("direct:test")
+    .doTry().
+        doTry().
+            throwException(new IllegalArgumentException("Forced by me"))
+        .doCatch(Exception.class)
+            .log("docatch 1")
+            .throwException(new IllegalArgumentException("Second forced by 
me"))
+    .doCatch(Exception.class)
+        .log("docatch 2")
+    .end();
+----
+
+Both `docatch 1` and `docatch 2` are in the inner `doTry`, and the outer 
`doTry` has no catch blocks.
+Use `endDoTry()` to end the blocks correctly:
+
+[source,java]
+----
+from("direct:test")
+    .doTry().
+        doTry().
+            throwException(new IllegalArgumentException("Forced by me"))
+        .doCatch(Exception.class)
+            .log("docatch 1")
+            .throwException(new IllegalArgumentException("Second forced by 
me"))
+         .endDoTry() // end this doCatch block
+     .endDoTry() // end the inner doTry
+    .doCatch(Exception.class)
+        .log("docatch 2")
+    .end();
+----
diff --git 
a/core/camel-core-engine/src/main/docs/modules/eips/pages/doTry-eip.adoc 
b/core/camel-core-engine/src/main/docs/modules/eips/pages/doTry-eip.adoc
new file mode 100644
index 000000000000..0b43a808862f
--- /dev/null
+++ b/core/camel-core-engine/src/main/docs/modules/eips/pages/doTry-eip.adoc
@@ -0,0 +1,246 @@
+= Do Try EIP
+:doctitle: Do Try
+:shortname: doTry
+:description: Wraps route steps in a try-catch-finally block for fine-grained 
exception handling within the route
+:since: 
+:supportlevel: Stable
+:tabs-sync-option:
+
+Camel supports the Java equivalent of try, catch, and finally directly in the 
DSL.
+It aims to work like its Java sisters but with more power.
+
+In Camel, we prefix the keywords with `do` to avoid having same keyword as 
Java.
+So we have:
+
+- `doTry`
+- `doCatch`
+- `doFinally`
+- `end` to end the block in Java DSL
+
+[IMPORTANT]
+====
+When using `doTry ... doCatch ... doFinally`, the regular Camel
+xref:manual::error-handler.adoc[Error Handler] is not in use; meaning any
+`onException` or the likes does not trigger.
+
+The reason is that
+`doTry ... doCatch ... doFinally` is in fact its own error handler and mimics 
how try/catch/finally works in Java.
+====
+
+== EIP options
+
+// eip options: START
+include::partial$eip-options.adoc[]
+// eip options: END
+
+== Using doTry ... doCatch ... doFinally
+
+In the route below we have all of them in action:
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+from("direct:start")
+    .doTry()
+        .process(new ProcessorFail())
+        .to("mock:result")
+    .doCatch(IOException.class, IllegalStateException.class)
+        .to("mock:catch")
+    .doFinally()
+        .to("mock:finally")
+    .end();
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+  <from uri="direct:start"/>
+  <doTry>
+    <process ref="processorFail"/>
+    <to uri="mock:result"/>
+    <doCatch>
+      <exception>java.io.IOException</exception>
+      <exception>java.lang.IllegalStateException</exception>
+      <to uri="mock:catch"/>
+    </doCatch>
+    <doFinally>
+       <to uri="mock:finally"/>
+    </doFinally>
+  </doTry>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:start
+      steps:
+        - doTry:
+            steps:
+              - process:
+                  ref: processorFail
+              - to:
+                  uri: mock:result
+              - doCatch:
+                  exception:
+                    - java.io.IOException
+                    - java.lang.IllegalStateException
+                  steps:
+                    - to:
+                        uri: mock:catch
+              - doFinally:
+                  steps:
+                    - to:
+                        uri: mock:finally
+----
+====
+
+=== Using onWhen with doCatch
+
+You can use xref:manual::predicate.adoc[Predicates] with `doCatch` to make it 
determine at runtime if the block should be triggered or not.
+In this example, we only want to trigger if the caused exception message 
contains the word *Damn*.
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+from("direct:start")
+    .doTry()
+        .process(new ProcessorFail())
+        .to("mock:result")
+    .doCatch(IOException.class, IllegalStateException.class)
+        .onWhen(exceptionMessage().contains("Damn"))
+        .to("mock:catch")
+    .doCatch(CamelExchangeException.class)
+        .to("mock:catchCamel")
+    .doFinally()
+        .to("mock:finally")
+    .end();
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+  <from uri="direct:start"/>
+  <doTry>
+    <process ref="processorFail"/>
+    <to uri="mock:result"/>
+    <doCatch>
+      <exception>java.io.IOException</exception>
+      <exception>java.lang.IllegalStateException</exception>
+      <onWhen>
+        <simple>${exception.message} contains 'Damn'</simple>
+      </onWhen>
+      <to uri="mock:catch"/>
+    </doCatch>
+    <doCatch>
+      <exception>org.apache.camel.CamelExchangeException</exception>
+      <to uri="mock:catchCamel"/>
+    </doCatch>
+    <doFinally>
+       <to uri="mock:finally"/>
+    </doFinally>
+  </doTry>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:start
+      steps:
+        - doTry:
+            steps:
+              - process:
+                  ref: processorFail
+              - to:
+                  uri: mock:result
+              - doCatch:
+                  exception:
+                    - java.io.IOException
+                    - java.lang.IllegalStateException
+                  steps:
+                    - onWhen:
+                        expression:
+                          simple:
+                            expression: "${exception.message} contains 'Damn'"
+                    - to:
+                        uri: mock:catch
+              - doCatch:
+                  exception:
+                    - org.apache.camel.CamelExchangeException
+                  steps:
+                    - to:
+                        uri: mock:catchCamel
+              - doFinally:
+                  steps:
+                    - to:
+                        uri: mock:finally
+----
+====
+
+=== Use end() to end the block
+
+When using Java DSL you must use `end()` to indicate where the try ... catch 
... finally block ends.
+If the route has a `doFinally`, then the `end()` should be at the end of the 
finally block.
+If there is no `doFinally`, then the `end()` should be at the end of the last 
`doCatch`.
+
+TIP: Instead of `end()` you can use `endDoTry()` to end and _return back_ to 
the try ... catch scope.
+
+=== Nested doTry ... doCatch
+
+When nesting `doTry ... doCatch` from an outer `doTry ... doCatch` EIP,
+pay extra attention when using Java DSL as the Java programming language is 
not _indent aware_
+so you may write code that is indented in a way where you think a catch block 
is associated with the other doTry, but it is not.
+
+Given the following Java DSL:
+
+[source,java]
+----
+from("direct:test")
+    .doTry().
+        doTry().
+            throwException(new IllegalArgumentException("Forced by me"))
+        .doCatch(Exception.class)
+            .log("docatch 1")
+            .throwException(new IllegalArgumentException("Second forced by 
me"))
+    .doCatch(Exception.class)
+        .log("docatch 2")
+    .end();
+----
+
+Both `docatch 1` and `docatch 2` are in the inner `doTry`, and the outer 
`doTry` has no catch blocks.
+Use `endDoTry()` to end the blocks correctly:
+
+[source,java]
+----
+from("direct:test")
+    .doTry().
+        doTry().
+            throwException(new IllegalArgumentException("Forced by me"))
+        .doCatch(Exception.class)
+            .log("docatch 1")
+            .throwException(new IllegalArgumentException("Second forced by 
me"))
+         .endDoTry() // end this doCatch block
+     .endDoTry() // end the inner doTry
+    .doCatch(Exception.class)
+        .log("docatch 2")
+    .end();
+----
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CatalogTab.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CatalogTab.java
index 65852839d7bd..113b4a8d269a 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CatalogTab.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CatalogTab.java
@@ -578,7 +578,11 @@ class CatalogTab extends AbstractTableTab {
                 }
             }
 
+            Set<String> skipEips = Set.of("when", "otherwise");
             for (String name : eipNames) {
+                if (skipEips.contains(name)) {
+                    continue;
+                }
                 EipModel model = catalog.eipModel(name);
                 if (model == null) {
                     continue;

Reply via email to