【Salesforce】Apexバッチで発生したガバナ制限エラーを通知する方法
やりたいこと
Apexバッチ(一括処理)で、ガバナ制限エラーが発生した場合にユーザへ通知したい。
背景
ApexのTry-Catchでは、Salesforce Platform 内部エラーや、ガバナ制限に達したために発生する LimitExceptions などをキャッチできない。
解決方法のポイント
・Apex 一括処理にて、Salesforce Platform 内部エラーまたはガバナ制限に達したために発生したときにプラットフォームイベントを起動します。
・イベントをリスンするクライアントとして、RaisesPlatformEventsオブジェクトのApexトリガを作成します。
・イベンドメッセ-ジから詳細なエラーの追跡情報を取得して、カスタムApexロジックにてメール送信します。
使用する機能
・Database.RaisesPlatformEvents インターフェース
・BatchApexErrorEventオブジェクトとトリガ
バッチの作成
★ポイント:プラットフォームイベントを起動するには、Apex 一括処理クラス宣言で Database.RaisesPlatformEvents インターフェースを実装する必要があります。
下記の例では、発行される DML ステートメントの合計数を、151以上になるように記載し、ガバナ制限の例外を発生させています。
global class ContactCreateBatch implements Database.Batchable<sObject>,Database.RaisesPlatformEvents{
global Database.QueryLocator start(Database.BatchableContext BC){
return Database.getQueryLocator('Select id,name from Account Limit 1000');
}
global void execute(Database.BatchableContext BC, List<sObject> scope){
Integer recordIndex=0;
for(sobject s : scope){
Account acc =(Account)s;
for(Integer i = 0; i <= 200; i++){
Contact con = new Contact();
con.AccountId = acc.id;
con.LastName = 'TEST';
Database.SaveResult sr = Database.insert(con);
}
}
}
global void finish(Database.BatchableContext BC){}
}
BatchApexErrorEventのApexトリガ作成
★ポイント:RaisesPlatformEventsオブジェクトにイベントが登録される発火するApexトリガを作成します。
下記の例では、一括処理トランザクションで失敗した取引先IDや、発生した例外内容などを、メール通知しています。
trigger BatchApexErrorEventTrigger on BatchApexErrorEvent (after insert) {
Set<Id> asyncApexJobIds = new Set<Id>();
for(BatchApexErrorEvent evt:Trigger.new){
asyncApexJobIds.add(evt.AsyncApexJobId);
}
Map<Id,AsyncApexJob> jobs = new Map<Id,AsyncApexJob>(
[SELECT id, ApexClass.Name FROM AsyncApexJob WHERE Id IN :asyncApexJobIds]
);
String subject = '[一括処理でエラーです]{0}';
String body = '';
for(BatchApexErrorEvent evt : Trigger.new){
subject = String.format(subject, new List<String>{jobs.get(evt.AsyncApexJobId).ApexClass.Name});
body += 'ExceptionType:'+ evt.ExceptionType+ '\n';
body += 'JobScope:'+ evt.JobScope+ '\n';
body += 'Message:'+ evt.Message+ '\n';
body += 'Phase:'+ evt.Phase+ '\n';
body += 'StackTrace:'+ evt.StackTrace+ '\n';
}
Set<String> mailSet = new Set<String>();
mailSet.add('*****@nddhq.co.jp');
String[] strAry = new List<String>(mailSet);
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddresses(strAry);
mail.setSubject(subject);
mail.setPlainTextBody(body);
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}
メール通知結果
下記は、上記トリガ処理で送信されたメールです。自動化プロセスが送信元になっています。
まとめ
本投稿では、メール通知処理を記載しました。
他にもBatchApexErrorEventトリガ内に、一括処理でエラーとなったレコードIDを保持しているため、当該エラーレコードに何かしらの更新をするなどの応用も可能ですね。
関連記事
Apex 一括処理からのプラットフォームイベントの起動
BatchApexErrorEvent
イベント登録のデバッグログの設定