0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Apache Camel × Spring Boot(XML DSL)で onException + handled を使った例外処理まとめ

Posted at

81FA51BD-3EC8-4EEA-B238-793305DCF245.png

Apache Camel を使って Spring Boot 上でルーティングを構築していると、例外処理の設計が非常に重要になります。
特に Camel の <onException><handled> の使い方を正しく理解することで、ルートの安定性や柔軟性が大きく向上します。

この記事では、基本構文から split 処理内の例外ハンドリング、そしてユースケース別の使い分けパターンまでを網羅的に解説します。


使用バージョン

  • Apache Camel 4.x
  • Spring Boot 3.x
  • DSL:XML DSL

基本構文(onException + handled)

<onException>
    <exception>java.lang.Exception</exception>
    <handled>
        <constant>true</constant>
    </handled>
    <log message="例外をハンドリングしました"/>
    <to uri="mock:error"/>
</onException>

handled の true / false の違い

設定値 動作の意味 Camel の挙動 ルートの継続
<constant>true</constant> 例外を処理済みにする 上位に例外をスローしない 継続する or 終了(明示的制御)
<constant>false</constant> 例外を未処理として扱う → 再スローする Camel が例外として再スローする 中断される
  • true:ログを出して終了したり、エラールートに流したりするのに最適
  • false:例外を上位に伝播させたいときに使用(テストや REST API 連携など)

サンプルルート:例外を補足して別ルートへ

<routes xmlns="http://camel.apache.org/schema/spring">

    <!-- 特定の例外をキャッチして処理済みにする -->
    <onException>
        <exception>java.lang.IllegalArgumentException</exception>
        <handled>
            <constant>true</constant>
        </handled>
        <log message="IllegalArgumentException をハンドリング"/>
        <to uri="mock:handled"/>
    </onException>

    <route id="mainRoute">
        <from uri="direct:start"/>
        <process>
            <bean ref="throwingBean"/>
        </process>
        <to uri="mock:result"/>
    </route>

</routes>
@Component("throwingBean")
public class ThrowingBean implements Processor {
    @Override
    public void process(Exchange exchange) {
        throw new IllegalArgumentException("テスト例外");
    }
}

応用:条件付きで handled にする

<handled>
    <simple>${exception.message} contains '非致命'</simple>
</handled>

応用:split の中で例外をキャッチしつつ処理を継続する

<route id="splitRoute">
    <from uri="direct:start"/>

    <split>
        <simple>${body}</simple>
        <parallelProcessing>false</parallelProcessing>

        <onException>
            <exception>java.lang.Exception</exception>
            <handled>
                <constant>true</constant>
            </handled>
            <log message="スプリット要素で例外を補足しスキップ"/>
            <to uri="mock:error"/>
        </onException>

        <process ref="itemProcessor"/>
        <to uri="mock:each"/>
    </split>

    <to uri="mock:done"/>
</route>
@Component("itemProcessor")
public class ItemProcessor implements Processor {
    @Override
    public void process(Exchange exchange) {
        String item = exchange.getIn().getBody(String.class);
        if ("NG".equals(item)) {
            throw new RuntimeException("NG項目が含まれています");
        }
    }
}

【用途別】Camel の <handled> の使い分け早見表

ユースケース handled の値 理由・意図 備考
バッチ処理中の一部エラーをスキップ true エラーを処理済みにし、次のメッセージに進みたい split 内での定型パターン
Kafka/S3送信失敗時に再送処理に回す true エラーを補足して「再送」ルートへ渡す 再送トピックや deadLetterChannel へ分岐
REST API で 500 を返す false 例外を外部(Spring Boot)へ伝播し、HTTPエラーを返すため Spring MVC / WebFlux との連携想定
テストで例外を検知して失敗させたい false Camel テスト内で例外を catch せず、JUnit で検証したい mockEndpoint.assertIsSatisfied() 失敗を狙うケースなど
ログだけ出して処理を終了したい(無視はしない) true ユーザー通知や監視は必要だが、処理は止めたい log + stopto("mock:alert") で終了
一部の例外だけスキップ(条件付き) 条件付き handled メッセージ内容や例外内容で柔軟に制御 <simple>${exception.message} contains '~'</simple>

おわりに

Camel の例外処理は「どこで止めるか・伝播させるか」を設計でしっかり決めることが重要です。
<handled> を正しく使い分けることで、堅牢かつ柔軟なルート構成が可能になります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?