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;
