Part 11: プラットフォームイベントとスケジュールバッチのエラーハンドリング

## **Part 11: プラットフォームイベントとスケジュールバッチのエラーハンドリング**

前回は **フューチャーメソッド (Future Methods) と Queueable Apex** のエラーハンドリングを解説しました。  
今回は **プラットフォームイベント (Platform Events) と スケジュールバッチ (Scheduled Batch Apex) のエラーハンドリング** に焦点を当てます。

---

## **1. プラットフォームイベント (Platform Events) のエラーハンドリング**

### **1.1. プラットフォームイベントの特徴**
- **非同期メッセージング** を利用して、システム間のデータ連携や、Salesforce内でのリアルタイム処理を実現
- **イベントの発行 (Publish) と購読 (Subscribe) に分かれる**
- **トリガー (Trigger) で処理を実行できる**
- **エラー発生時はイベントを再処理できないため、エラーログを残すことが重要**

---

### **1.2. プラットフォームイベントのエラーハンドリング実装例**

#### ✅ **OK 例: 例外キャッチ + エラーログ**
```apex
trigger PlatformEventTrigger on MyPlatformEvent__e (after insert) {
    for (MyPlatformEvent__e event : Trigger.New) {
        try {
            // 例: アカウントの更新処理
            Account acc = [SELECT Id FROM Account WHERE Id = :event.AccountId__c LIMIT 1];
            acc.Industry = event.Industry__c;
            update acc;
        } catch (DmlException e) {
            ErrorLogService.logError(e, 'PlatformEventTrigger', 'handleEvent');
        } catch (Exception e) {
            ErrorLogService.logError(e, 'PlatformEventTrigger', 'handleEvent');
        }
    }
}
```

このコードでは：
- **`try-catch` を使用してエラーハンドリング**
- **エラーログ (`ErrorLogService.logError()`) を記録**
- **イベントは再処理できないため、ログを見て手動で対応することが必要**

> **適用ケース:**  
> **リアルタイムのデータ処理を行うが、エラー発生時も他の処理に影響を与えないようにする場合**

---

## **2. スケジュールバッチ (Scheduled Batch Apex) のエラーハンドリング**

### **2.1. スケジュールバッチの特徴**
- **定期実行のバッチ処理**
- **`System.schedule()` を使用してスケジュール登録**
- **例外発生時はエラーメールを送るか、リトライする仕組みが必要**

---

### **2.2. スケジュールバッチのエラーハンドリング実装例**

#### ✅ **OK 例: try-catch でエラーハンドリング**
```apex
global class ScheduledBatchExample implements Schedulable {
    global void execute(SchedulableContext sc) {
        try {
            System.enqueueJob(new BatchExample()); // バッチ処理をキューに登録
        } catch (Exception e) {
            ErrorLogService.logError(e, 'ScheduledBatchExample', 'execute');
        }
    }
}
```

このコードでは：
- **`System.enqueueJob(new BatchExample())` でバッチをキューに登録**
- **例外をキャッチしてエラーログに記録**
- **スケジュール実行時にエラーが発生しても、他の処理に影響を与えないようにする**

> **適用ケース:**  
> **毎日定期的にバッチ処理を実行し、エラーが発生しても影響を最小限に抑えたい場合**

---

### **2.3. エラー発生時の再実行**
スケジュールバッチは **1 回実行された後、失敗しても自動リトライされない** ため、  
**エラーが発生した場合に再実行する仕組みを追加** すると良い。

#### ✅ **OK 例: エラー時に再実行**
```apex
global class ScheduledBatchRetry implements Schedulable {
    global void execute(SchedulableContext sc) {
        try {
            System.enqueueJob(new BatchExample());
        } catch (Exception e) {
            ErrorLogService.logError(e, 'ScheduledBatchRetry', 'execute');
            
            // 1時間後に再実行
            String cronExp = '0 0 1 * * ?'; // 毎日午前1時に実行
            System.schedule('Retry Batch Example', cronExp, new ScheduledBatchRetry());
        }
    }
}
```

このコードでは：
- **エラー発生時に `System.schedule()` を使って 1 時間後に再実行**
- **無限ループを防ぐため、ログを記録して管理者が状況を確認できるようにする**

> **適用ケース:**  
> **定期的なバッチ実行で、一時的なエラー (API タイムアウトなど) が発生した場合に再実行したい場合**

---

### **2.4. エラーメール通知**
バッチ処理でエラーが発生した場合、管理者にメールで通知するのが有効。

#### ✅ **OK 例: エラー発生時にメール通知**
```apex
global class ScheduledBatchWithEmail implements Schedulable {
    global void execute(SchedulableContext sc) {
        try {
            System.enqueueJob(new BatchExample());
        } catch (Exception e) {
            ErrorLogService.logError(e, 'ScheduledBatchWithEmail', 'execute');

            // エラーメール送信
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
            mail.setToAddresses(new String[] {'admin@example.com'});
            mail.setSubject('【警告】スケジュールバッチエラー発生');
            mail.setPlainTextBody('エラー内容: ' + e.getMessage());
            Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
        }
    }
}
```

このコードでは：
- **エラー発生時に `Messaging.sendEmail()` を使って管理者に通知**
- **エラーの詳細 (例外メッセージ) をメールに記載**

> **適用ケース:**  
> **バッチ処理が失敗したことをすぐに管理者に通知し、早急に対応できるようにする場合**

---

## **まとめ**
今回は **プラットフォームイベントとスケジュールバッチのエラーハンドリング** を解説しました。

✅ **プラットフォームイベント**
- **`try-catch` でエラーハンドリング**
- **エラーログ (`ErrorLogService.logError()`) を記録**
- **イベントは再処理できないため、ログを見て手動で対応**

✅ **スケジュールバッチ**
- **`try-catch` でエラーハンドリング**
- **エラー発生時に `System.schedule()` で再実行**
- **`Messaging.sendEmail()` を使って管理者にメール通知**

> **次の Part 12** では、**ガバナ制限 (Governor Limits) の超過を防ぐためのエラーハンドリング** を解説します！