This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch fix/CAMEL-25467 in repository https://gitbox.apache.org/repos/asf/camel-jbang-examples.git
commit 42ce150bf440ff158580702119ba755e63992806 Author: Claus Ibsen <[email protected]> AuthorDate: Wed Oct 14 08:15:09 2026 +0200 CAMEL-25467: error-handling gives the parked route a file and an error handler of its own The parked route received the failures of the dead letter channel and the onException of error-handling.camel.yaml, and used them too: a failure in parking an order went back to parked, with its own exception in place of the first, which camel overview now warns about. The route is now in parked.camel.yaml with a dead letter channel of its own to a log, as the error handling of a file applies to the routes in that file only. The README says why, and its expected output gets the warning of the declined card. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- fail-well/error-handling/README.md | 17 +++++++++++++---- fail-well/error-handling/error-handling.camel.yaml | 21 ++------------------- fail-well/error-handling/parked.camel.yaml | 22 ++++++++++++++++++++++ .../test/error-handling.citrus.it.yaml | 1 + 4 files changed, 38 insertions(+), 23 deletions(-) diff --git a/fail-well/error-handling/README.md b/fail-well/error-handling/README.md index 00b24b2..2f6d6e6 100644 --- a/fail-well/error-handling/README.md +++ b/fail-well/error-handling/README.md @@ -11,8 +11,9 @@ INFO ... error-handling.camel.yaml:40 : Payment for ORD-1001 charged, 2 line(s) WARN ... DeadLetterChannel : Failed delivery for (...). On delivery attempt: 0 caught: java.net.ConnectException: payment provider did not answer WARN ... DeadLetterChannel : Failed delivery for (...). On delivery attempt: 1 caught: java.net.ConnectException: payment provider did not answer INFO ... error-handling.camel.yaml:40 : Payment for ORD-1002 charged, 1 line(s) to the warehouse +WARN ... DeadLetterChannel : Failed delivery for (...). On delivery attempt: 0 caught: java.lang.IllegalStateException: card declined INFO ... error-handling.camel.yaml:21 : Payment for ORD-1003 declined: card declined -INFO ... error-handling.camel.yaml:75 : Order ORD-1003 parked for manual review: card declined +INFO ... parked.camel.yaml:13 : Order ORD-1003 parked for manual review: card declined ``` ## Install Camel CLI @@ -41,14 +42,19 @@ ends up in `parked/order-1003.json`. failed, and a step that always throws would always fail; the provider answers on the third attempt because it reads `CamelRedeliveryCounter`. - The parked route can use `${exception.message}` because the error handler keeps the exception on the exchange. +- The parked route is in a file of its own, `parked.camel.yaml`, with an error handler of its own: a dead letter + channel to a log. The `errorHandler` and `onException` of `error-handling.camel.yaml` apply to the routes in that + file only. In the same file, a failure in parking an order would go back to the parked route, with its own + exception in place of the first, which `camel overview` warns about. ## Build it step by step 1. A `file` route on `orders` that unmarshals each order, calls `direct:charge` and logs the payment; a second route from `direct:charge` that throws for ORD-1003. Without any error handler the failure is logged with a stack trace and the order is dropped. -2. Add `errorHandler` with `deadLetterChannel` to `direct:parked` and a route that logs there. The stack - trace is gone and the order is parked, after three attempts a second apart. +2. Add `errorHandler` with `deadLetterChannel` to `direct:parked`, and the route that parks the order in + `parked.camel.yaml`, with a dead letter channel of its own to a log. The stack trace is gone and the order is + parked, after three attempts a second apart. 3. Add `noErrorHandler` to the provider route and make it throw `ConnectException` for ORD-1002 unless `CamelRedeliveryCounter` is 2: two warnings, then charged. 4. Add the `onException` for the declined card with no retries. @@ -57,7 +63,10 @@ ends up in `parked/order-1003.json`. - Raise `maximumRedeliveries` to 5 with `backOffMultiplier: 2` and `useExponentialBackOff: true` and watch the delays grow. -- Replace `direct:parked` with a file endpoint straight in `deadLetterUri` and drop the parked route. +- Replace `direct:parked` with a file endpoint straight in `deadLetterUri` and in the `onException`, and drop the + parked route. +- Move the parked route into `error-handling.camel.yaml` and run `camel overview`: it warns that a failure in parked + goes back to parked. - Make the provider fail for every order and see all three parked. ## Integration testing diff --git a/fail-well/error-handling/error-handling.camel.yaml b/fail-well/error-handling/error-handling.camel.yaml index 8d9f006..485c162 100644 --- a/fail-well/error-handling/error-handling.camel.yaml +++ b/fail-well/error-handling/error-handling.camel.yaml @@ -1,5 +1,5 @@ -# Payment for the web shop orders. The payment provider is flaky for one order -# and declines another; the error handler retries the first and parks both. +# Payment for the web shop orders. The payment provider is flaky for one order and declines +# another: the first is retried until it is charged, the second parked (parked.camel.yaml). - errorHandler: deadLetterChannel: deadLetterUri: direct:parked @@ -65,20 +65,3 @@ - throwException: exceptionType: java.lang.IllegalStateException message: "card declined" - -# Parked orders are written as files for someone to look at -- route: - id: parked - from: - uri: direct:parked - steps: - - log: - message: "Order ${body[orderId]} parked for manual review: ${exception.message}" - - marshal: - json: - library: Jackson - - to: - uri: file - parameters: - directoryName: parked - fileName: "${header.CamelFileName}" diff --git a/fail-well/error-handling/parked.camel.yaml b/fail-well/error-handling/parked.camel.yaml new file mode 100644 index 0000000..8fe9d72 --- /dev/null +++ b/fail-well/error-handling/parked.camel.yaml @@ -0,0 +1,22 @@ +# Parked orders are written as files for someone to look at. The route has a file +# and an error handler of its own: the error handling of error-handling.camel.yaml, +# which sends the failed orders here, does not apply to it, so a failure in parking +# an order is logged, instead of being sent back here. +- route: + id: parked + errorHandler: + deadLetterChannel: + deadLetterUri: "log:parking-failed?level=ERROR" + from: + uri: direct:parked + steps: + - log: + message: "Order ${body[orderId]} parked for manual review: ${exception.message}" + - marshal: + json: + library: Jackson + - to: + uri: file + parameters: + directoryName: parked + fileName: "${header.CamelFileName}" diff --git a/fail-well/error-handling/test/error-handling.citrus.it.yaml b/fail-well/error-handling/test/error-handling.citrus.it.yaml index 6c8446a..f6ab5fe 100644 --- a/fail-well/error-handling/test/error-handling.citrus.it.yaml +++ b/fail-well/error-handling/test/error-handling.citrus.it.yaml @@ -10,6 +10,7 @@ actions: systemProperties: file: "../application.properties" resources: + - "parked.camel.yaml" - "orders/order-1001.json" - "orders/order-1002.json" - "orders/order-1003.json"
