{"id":2088,"date":"2026-02-01T02:15:37","date_gmt":"2026-01-31T13:15:37","guid":{"rendered":"https:\/\/www.ronella.xyz\/?p=2088"},"modified":"2026-02-01T02:15:37","modified_gmt":"2026-01-31T13:15:37","slug":"apache-camel-error-handling-defaulterrorhandler-and-onexception","status":"publish","type":"post","link":"https:\/\/www.ronella.xyz\/?p=2088","title":{"rendered":"Apache Camel Error Handling: DefaultErrorHandler and onException"},"content":{"rendered":"<p>Apache Camel's robust error handling ensures reliable integration routes even when failures occur. The DefaultErrorHandler provides automatic retries and logging, while onException clauses offer precise control over specific exceptions.<\/p>\n<h2>Core Concepts<\/h2>\n<p><strong>DefaultErrorHandler<\/strong> is Camel\u2019s default strategy for all routes, featuring retry logic, detailed logging, and flexible recovery paths. It logs exceptions at ERROR level by default and supports configurable redeliveries without requiring dead letter channels. <\/p>\n<p><strong>onException<\/strong> clauses intercept specific exception types globally or per-route, with priority based on exception specificity\u2014most-derived classes match first. Use <code>handled(true)<\/code> to stop propagation and transform responses, or <code>continued(true)<\/code> to resume the route.<\/p>\n<h2>DefaultErrorHandler Configuration<\/h2>\n<p>Set global retry policies early in RouteBuilder\u2019s <code>configure()<\/code> method:<\/p>\n<pre><code class=\"language-java\">errorHandler(defaultErrorHandler()\n    .maximumRedeliveries(3)\n    .redeliveryDelay(2000)\n    .retryAttemptedLogLevel(LoggingLevel.WARN)\n    .logStackTrace(true));<\/code><\/pre>\n<p>Key options control retry behavior: <code>maximumRedeliveries<\/code> caps attempts, <code>redeliveryDelay<\/code> sets wait time (with exponential backoff), and <code>retryAttemptedLogLevel<\/code> adjusts retry logging verbosity. Per-route overrides nest within <code>from()<\/code> endpoints for granular control.<\/p>\n<h2>onException Best Practices<\/h2>\n<p>Place onException handlers before route definitions for global scope. Multiple handlers for the same exception type chain by priority, with conditions via <code>onWhen()<\/code>:<\/p>\n<pre><code class=\"language-java\">onException(IOException.class)\n    .handled(true)\n    .log(&quot;\ud83d\udea8 IO EXCEPTION: ${exception.message}&quot;)\n    .to(&quot;direct:ioErrorHandler&quot;);\n\nonException(IllegalArgumentException.class)\n    .onWhen(exchange -&gt; &quot;high&quot;.equals(exchange.getIn().getHeader(&quot;error.priority&quot;)))\n    .handled(true)\n    .log(&quot;\u26a0\ufe0f HIGH PRIORITY: ${exception.message}&quot;);<\/code><\/pre>\n<p>The <code>handled(true)<\/code> flag clears the exception and prevents DefaultErrorHandler retries unless <code>continued(true)<\/code> is specified. Route to dedicated error flows like <code>direct:ioErrorHandler<\/code> for consistent processing.<\/p>\n<h2>Example<\/h2>\n<p>This self-contained demo showcases layered error handling across exception types, conditional logic, and retry policies:<\/p>\n<pre><code class=\"language-java\">import org.apache.camel.*;\nimport org.apache.camel.builder.RouteBuilder;\nimport org.apache.camel.impl.DefaultCamelContext;\n\npublic class CamelErrorHandlingDemo extends RouteBuilder {\n\n    @Override\n    public void configure() throws Exception {\n        \/\/ Global DefaultErrorHandler with retries\n        errorHandler(defaultErrorHandler()\n            .maximumRedeliveries(3)\n            .redeliveryDelay(2000)\n            .retryAttemptedLogLevel(LoggingLevel.WARN)\n            .logStackTrace(true));\n\n        \/\/ Specific exception handlers (priority: most specific first)\n        onException(java.io.IOException.class)\n            .handled(true)\n            .log(&quot;\ud83d\udea8 IO EXCEPTION HANDLED FIRST: ${exception.message}&quot;)\n            .to(&quot;direct:ioErrorHandler&quot;);\n\n        onException(IllegalArgumentException.class)\n            .maximumRedeliveries(2)\n            .redeliveryDelay(1000)\n            .onWhen(exchange -&gt; &quot;high&quot;.equals(exchange.getIn().getHeader(&quot;error.priority&quot;)))\n            .handled(true)\n            .log(&quot;\u26a0\ufe0f HIGH PRIORITY ARG EXCEPTION: ${exception.message}&quot;)\n            .to(&quot;direct:argErrorHandler&quot;);\n\n        onException(IllegalArgumentException.class)\n            .handled(true)\n            .log(&quot;\u26a0\ufe0f DEFAULT ARG EXCEPTION: ${exception.message}&quot;)\n            .to(&quot;direct:argErrorHandler&quot;);\n\n        onException(Exception.class)\n            .handled(true)\n            .log(&quot;\ud83d\udc80 GENERIC EXCEPTION: ${exception.message}&quot;)\n            .to(&quot;direct:deadLetterQueue&quot;);\n\n        \/\/ Main processing route\n        from(&quot;direct:start&quot;)\n            .routeId(&quot;mainRoute&quot;)\n            .log(&quot;Processing: ${body}&quot;)\n            .process(mainProcessor())\n            .to(&quot;direct:success&quot;);\n\n        from(&quot;direct:success&quot;).log(&quot;\u2705 SUCCESS: ${body}&quot;);\n        from(&quot;direct:ioErrorHandler&quot;).log(&quot;\ud83d\udcc1 IO Error handled&quot;).setBody(constant(&quot;IO_PROCESSED&quot;));\n        from(&quot;direct:argErrorHandler&quot;).log(&quot;\ud83d\udd04 Arg error processed&quot;).setBody(constant(&quot;ARG_PROCESSED&quot;));\n        from(&quot;direct:deadLetterQueue&quot;).log(&quot;\u26b0\ufe0f DLQ: ${exception.stacktrace}&quot;).setBody(constant(&quot;DLQ_PROCESSED&quot;));\n    }\n\n    private static Processor mainProcessor() {\n        return exchange -&gt; {\n            String input = exchange.getIn().getBody(String.class);\n            switch (input != null ? input : &quot;&quot;) {\n                case &quot;io-fail&quot;:\n                    exchange.getIn().setHeader(&quot;error.priority&quot;, &quot;high&quot;);\n                    throw new java.io.IOException(&quot;\ud83d\udcbe Disk full&quot;);\n                case &quot;arg-high&quot;:\n                    exchange.getIn().setHeader(&quot;error.priority&quot;, &quot;high&quot;);\n                    throw new IllegalArgumentException(&quot;\u274c High priority invalid data&quot;);\n                case &quot;arg-normal&quot;:\n                    throw new IllegalArgumentException(&quot;\u274c Normal invalid data&quot;);\n                case &quot;generic-fail&quot;:\n                    throw new RuntimeException(&quot;Unknown error&quot;);\n                default:\n                    exchange.getIn().setBody(&quot;\u2705 Processed: &quot; + input);\n            }\n        };\n    }\n\n    public static void main(String[] args) throws Exception {\n        try (CamelContext context = new DefaultCamelContext()) {\n            context.getCamelContextExtension().setName(&quot;CamelErrorDemo&quot;);\n            context.addRoutes(new CamelErrorHandlingDemo());\n            context.start();\n\n            ProducerTemplate template = context.createProducerTemplate();\n            System.out.println(&quot;\ud83d\ude80 Camel Error Handling Demo...\\n&quot;);\n\n            template.sendBody(&quot;direct:start&quot;, &quot;io-fail&quot;);      \/\/ \u2192 IO handler\n            template.sendBody(&quot;direct:start&quot;, &quot;arg-high&quot;);     \/\/ \u2192 High priority arg\n            template.sendBody(&quot;direct:start&quot;, &quot;arg-normal&quot;);   \/\/ \u2192 Default arg  \n            template.sendBody(&quot;direct:start&quot;, &quot;generic-fail&quot;); \/\/ \u2192 Generic handler\n            template.sendBody(&quot;direct:start&quot;, &quot;good&quot;);         \/\/ \u2192 Success\n\n            Thread.sleep(8000);\n        }\n    }\n}<\/code><\/pre>\n<h2>Expected Demo Output<\/h2>\n<pre><code>textProcessing: io-fail\n\ud83d\udea8 IO EXCEPTION HANDLED FIRST: \ud83d\udcbe Disk full\n\ud83d\udcc1 IO Error handled\n\nProcessing: arg-high  \n\u26a0\ufe0f HIGH PRIORITY ARG EXCEPTION: \u274c High priority invalid data\n\ud83d\udd04 Arg error processed<\/code><\/pre>\n<h2>Production Tips<\/h2>\n<p>Test all failure paths during development using predictable payloads like the demo. Monitor <code>exchange.getProperty(Exchange.REDELIVERY_COUNTER)<\/code> for retry stats. For complex flows, combine with <code>doTry().doCatch()<\/code> blocks for local exception handling within routes. This approach scales from simple REST APIs to enterprise integration patterns.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Apache Camel&#8217;s robust error handling ensures reliable integration routes even when failures occur. The DefaultErrorHandler provides automatic retries and logging, while onException clauses offer precise control over specific exceptions. Core Concepts DefaultErrorHandler is Camel\u2019s default strategy for all routes, featuring retry logic, detailed logging, and flexible recovery paths. It logs exceptions at ERROR level by [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[92],"tags":[],"_links":{"self":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/2088"}],"collection":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2088"}],"version-history":[{"count":1,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/2088\/revisions"}],"predecessor-version":[{"id":2089,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/2088\/revisions\/2089"}],"wp:attachment":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2088"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2088"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2088"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}