0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Part 8: トリガー のエラーハンドリングとリカバリ方法

Posted at

Part 8: トリガー (Trigger) のエラーハンドリングとリカバリ方法

前回は エラーログ管理リトライ機構 を解説しました。
今回は Apex トリガーにおけるエラーハンドリング と、エラー発生時のリカバリ方法 について解説します。


1. トリガーのエラーハンドリングの基本原則

1.1. トリガーでのエラーの特徴

Apex トリガーでは、エラーが発生するとその処理全体がロールバック されます。
つまり、エラーが発生したレコードだけでなく、処理中のすべてのレコードが保存されません

例えば、before insert トリガーで 10 件のレコードを処理中に 1 件がエラーになった場合、
すべてのレコードがロールバック されます。


1.2. トリガーのエラーハンドリング戦略

トリガー内でのエラーハンドリングの考え方は以下の 3 つです。

戦略 概要 適用ケース
全体をロールバック 例外をスローして処理を中断 データ整合性を最優先する場合
部分的にエラーを記録 エラーのあるレコードのみ処理対象から除外 エラーを許容できる場合
エラーレポートを作成 addError() を使用して、エラーをレコード単位で通知 ユーザーにエラーをフィードバックしたい場合

2. 例外をスローして処理を中断する (全体をロールバック)

✅ NG 例: トリガー内で直接 try-catch

trigger AccountTrigger on Account (before insert) {
    try {
        for (Account acc : Trigger.new) {
            acc.Name = acc.Name.toUpperCase(); // 例: アカウント名を大文字にする
        }
    } catch (Exception e) {
        System.debug('エラー発生: ' + e.getMessage()); 
        // → ただのデバッグログなので、処理は継続してしまう
    }
}

このコードでは エラーがキャッチされても処理が継続するため、問題のあるデータがそのまま保存されるリスクがあります


✅ OK 例: TriggerHandler クラスでエラーを適切に処理

トリガー内ではなく 別のクラスでエラーハンドリングを行い、適切にスローする のがベストプラクティスです。

🔹 AccountTriggerHandler クラス

public class AccountTriggerHandler {
    public static void beforeInsert(List<Account> newAccounts) {
        for (Account acc : newAccounts) {
            if (String.isEmpty(acc.Name)) {
                throw new CustomTriggerException('アカウント名が空です');
            }
            acc.Name = acc.Name.toUpperCase();
        }
    }
}

🔹 CustomTriggerException クラス

public class CustomTriggerException extends Exception {}

🔹 AccountTrigger (トリガー)

trigger AccountTrigger on Account (before insert) {
    try {
        AccountTriggerHandler.beforeInsert(Trigger.new);
    } catch (CustomTriggerException e) {
        System.debug('エラー発生: ' + e.getMessage());
        throw e; // 例外をスローしてロールバック
    }
}

この実装では、
エラーが発生した場合に throw e; で明示的にスローし、全体をロールバック できます。

適用ケース: データの整合性を重視する場合


3. エラーのあるレコードのみ除外して処理を続行 (部分的エラー処理)

3.1. try-catch を使用して問題のあるレコードだけ処理をスキップ

エラーが発生したレコードだけスキップし、他のレコードは処理を続ける 方法です。

✅ OK 例: ErrorLogService を利用したエラーハンドリング

public class AccountTriggerHandler {
    public static void beforeInsert(List<Account> newAccounts) {
        List<Account> validAccounts = new List<Account>();

        for (Account acc : newAccounts) {
            try {
                if (String.isEmpty(acc.Name)) {
                    throw new CustomTriggerException('アカウント名が空です');
                }
                acc.Name = acc.Name.toUpperCase();
                validAccounts.add(acc);
            } catch (CustomTriggerException e) {
                ErrorLogService.logError(e, 'AccountTriggerHandler', 'beforeInsert');
            }
        }

        if (!validAccounts.isEmpty()) {
            insert validAccounts;
        }
    }
}

このコードでは、

  • 正常なレコードだけ insert する
  • エラーのあるレコードはスキップし、エラーログに記録

適用ケース:
エラーを許容しつつ、可能な限り処理を進めたい場合


4. addError() でユーザーにエラーを通知する

addError() を使うと、エラーメッセージを直接レコードに追加し、処理を中断 できます。
ロールバックされるが、どのレコードに問題があったか UI で確認できるのが利点 です。

✅ OK 例: addError() を使用

public class AccountTriggerHandler {
    public static void beforeInsert(List<Account> newAccounts) {
        for (Account acc : newAccounts) {
            if (String.isEmpty(acc.Name)) {
                acc.addError('アカウント名は必須です'); // エラーメッセージをレコードに追加
            }
        }
    }
}

これにより、

エラー発生時に Salesforce の UI でエラーメッセージが表示されるため、ユーザーが問題を認識しやすくなります。

適用ケース:
エラーの詳細をユーザーに伝えたい場合


5. エラーリカバリ戦略

エラーが発生した際の対応方法を整理すると、以下のようになります。

リカバリ方法 適用ケース 実装方法
ロールバック データ整合性が最優先 throw new Exception();
エラーを記録しつつ続行 一部エラーは許容し、できるだけ処理を進める ErrorLogService.logError() を利用
ユーザーにエラーメッセージを通知 データ入力者にフィードバックが必要 addError() を使用

まとめ

今回は Apex トリガーのエラーハンドリングとリカバリ方法 を解説しました。

  • トリガー内で try-catch を使わず、ハンドラクラスで処理
  • throw e; を使い、エラー発生時に全体をロールバック
  • エラーのあるレコードだけ除外し、可能な限り処理を続行
  • addError() を使ってユーザーにフィードバック

次の Part 9 では、バッチ処理 (Batch Apex) におけるエラーハンドリング について解説します!

0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?