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?

Part 10: フューチャーメソッドと Queueable Apex のエラーハンドリング

Posted at

Part 10: フューチャーメソッド (Future Methods) と Queueable Apex のエラーハンドリング

前回は バッチ処理 (Batch Apex) のエラーハンドリング を解説しました。
今回は 非同期処理のエラーハンドリング として、
フューチャーメソッド (Future Methods) と Queueable Apex に焦点を当てます。


1. フューチャーメソッドのエラーハンドリング

1.1. フューチャーメソッドの特徴

フューチャーメソッド (@future) は 非同期で処理を実行 し、
トランザクションの制限を回避する のに役立ちます。
特に コールアウト (外部 API 呼び出し) や大量データの DML に使われます。

1.2. フューチャーメソッドのエラーハンドリングの課題

  • 通常の try-catch でエラーを処理できるが、エラーログを残さないと気づきにくい
  • 発生したエラーは呼び出し元に通知されない
  • 実行失敗しても自動リトライはされない

2. フューチャーメソッドのエラーハンドリング実装例

OK 例: try-catch でエラーを記録

public class FutureExample {
    @future(callout=true)
    public static void updateAccountIndustry(Set<Id> accountIds) {
        try {
            List<Account> accounts = [SELECT Id, Industry FROM Account WHERE Id IN :accountIds];
            for (Account acc : accounts) {
                acc.Industry = 'Technology';
            }
            update accounts;
        } catch (DmlException e) {
            ErrorLogService.logError(e, 'FutureExample', 'updateAccountIndustry');
        } catch (Exception e) {
            ErrorLogService.logError(e, 'FutureExample', 'updateAccountIndustry');
        }
    }
}

このコードでは:

  • try-catch で例外をキャッチ
  • ErrorLogService.logError() でエラーメッセージを記録
  • エラー発生時も他の処理に影響を与えない

適用ケース:
非同期処理で DML 例外や予期しないエラーを記録し、原因を特定できるようにしたい場合


3. Queueable Apex のエラーハンドリング

3.1. Queueable Apex の特徴

Queueable Apex (System.Queueable) は フューチャーメソッドよりも柔軟 で、
オブジェクトをパラメータとして渡せる などの利点があります。
また、System.enqueueJob() を使ってキューに登録することで、複雑な非同期処理が可能 です。


4. Queueable Apex のエラーハンドリング実装例

OK 例: try-catch でエラーハンドリング

public class QueueableExample implements Queueable {
    private Set<Id> accountIds;

    public QueueableExample(Set<Id> accountIds) {
        this.accountIds = accountIds;
    }

    public void execute(QueueableContext context) {
        try {
            List<Account> accounts = [SELECT Id, Industry FROM Account WHERE Id IN :accountIds];
            for (Account acc : accounts) {
                acc.Industry = 'Technology';
            }
            update accounts;
        } catch (DmlException e) {
            ErrorLogService.logError(e, 'QueueableExample', 'execute');
        } catch (Exception e) {
            ErrorLogService.logError(e, 'QueueableExample', 'execute');
        }
    }
}

このコードでは:

  • Queueable インターフェースを実装し、execute() メソッド内で処理
  • try-catch を使用し、エラー発生時に ErrorLogService.logError() で記録

適用ケース:
非同期処理の中でオブジェクトを渡しつつ、エラー情報を記録したい場合


5. System.enqueueJob() を使った再実行の仕組み

フューチャーメソッドや Queueable Apex では、エラー発生時に 自動リトライされない ため、
エラーログに記録された場合に、一定時間後に再実行する仕組みを追加 できます。

OK 例: エラー時に再実行する

public class QueueableRetryExample implements Queueable {
    private Set<Id> accountIds;
    private Integer retryCount;

    public QueueableRetryExample(Set<Id> accountIds, Integer retryCount) {
        this.accountIds = accountIds;
        this.retryCount = retryCount;
    }

    public void execute(QueueableContext context) {
        try {
            List<Account> accounts = [SELECT Id, Industry FROM Account WHERE Id IN :accountIds];
            for (Account acc : accounts) {
                acc.Industry = 'Technology';
            }
            update accounts;
        } catch (DmlException e) {
            ErrorLogService.logError(e, 'QueueableRetryExample', 'execute');
            if (retryCount < 3) { // 最大3回リトライ
                System.enqueueJob(new QueueableRetryExample(accountIds, retryCount + 1));
            }
        } catch (Exception e) {
            ErrorLogService.logError(e, 'QueueableRetryExample', 'execute');
        }
    }
}

このコードでは:

  • 失敗した場合、最大 3 回まで System.enqueueJob() を使って再実行
  • 再実行回数を retryCount で管理し、無限ループを防ぐ

適用ケース:
一時的なエラー (ロック競合、外部 API のタイムアウト) が発生する可能性がある場合


6. エラーメールを送信

Queueable Apex でも、エラーが発生したら 管理者にメール通知 するのが有効です。

OK 例: エラー発生時にメール通知

public void execute(QueueableContext context) {
    try {
        // メイン処理
    } catch (Exception e) {
        ErrorLogService.logError(e, 'QueueableExample', 'execute');
        
        // 管理者にメール通知
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        mail.setToAddresses(new String[] {'admin@example.com'});
        mail.setSubject('【警告】Queueable Apex でエラー発生');
        mail.setPlainTextBody('エラー内容: ' + e.getMessage());
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
    }
}

適用ケース:
エラーを即座に管理者に通知したい場合


まとめ

今回は フューチャーメソッド (Future Methods) と Queueable Apex のエラーハンドリング を解説しました。

フューチャーメソッド

  • try-catch でエラーハンドリング
  • エラーログを記録し、管理者が原因を特定できるようにする

Queueable Apex

  • try-catch でエラーを記録
  • エラー時に System.enqueueJob() を使って再実行
  • エラーメール通知を追加して管理者に通知

次の Part 11 では、プラットフォームイベントや非同期処理 (Scheduled Apex, Event-Driven Architecture) におけるエラーハンドリング を解説します!

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?