3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

例外(AuraHandledException)をスローしつつDML操作を行う

Last updated at Posted at 2025-01-21

未処理の例外があるとDMLは行われない

LWCから呼び出されたApexでエラーが発生した時、AuraHandledExceptionをスローしてJavaScriptでエラーを処理することがあります。例外をスローするので、当然ロールバックが起きます。そのため、たとえばエラーログをレコードとして残したい時でも、通常のDML操作ではレコードが作成されません。また、futureメソッドも実行されません。

DMLが実行されない例(通常のDML)
public class SampleController {
    @AuraEnabled
    public static void doSomething() {
        try {
            // 処理
        } catch (Exception e) {
            // ロールバックされるためレコードが作成されない。
            insert createLog(e);
            throw new AuraHandledException(e.getMessage());
        }
    }

    private static Log__c createLog(Exception e) {
        return new Log__c(
            Message__c = e.getMessage(),
            DetailMessage__c = e.getStackTraceString()
        );
    }
}
DMLが実行されない例(futureメソッドでのDML)
public class SampleController {
    @AuraEnabled
    public static void doSomething() {
        try {
            // 処理
        } catch (Exception e) {
            // トランザクションがロールバックされるとFutureメソッドは処理されない。
            writeLogAsync(e.getMessage(), e.getStackTraceString());
            throw new AuraHandledException(e.getMessage());
        }
    }

    @Future
    private static void writeLogAsync(String message, String detail) {
        insert new Log__c(
            Message__c = message,
            DetailMessage__c = detail
        );
    }
}

例外を投げつつレコードを作成する場合はプラットフォームイベントを使用する

プラットフォームイベントは、すぐに公開するか、トランザクションが正常に終了した後に公開するかを選択することができます。すぐに公開を選択することで、処理されない例外が発生してロールバックが起きてもイベントトリガーを介してレコードを保存することができます。ただし、プラットフォームイベントには1日あたりのリミットがあるため、大量のイベントを発生させる場合は注意が必要です。

プラットフォームイベントの制限について

1. プラットフォームイベントを作成する

「設定 > プラットフォームイベント > 新規プラットフォームイベント」からプラットフォームイベントを作成します。このとき、公開動作は「すぐに公開」を選択します。作成後にカスタム項目も作成します。

スクリーンショット 2025-01-20 23.39.18.png

2. プラットフォームイベントトリガーフローを作成する

「設定 > フロー > 新規フロー」でプラットフォームイベントトリガーフローを選択して、プラットフォームイベントが登録された時にDML操作を行うフローを作成します。

image.png

image.png

3. Apexでプラットフォームイベントを公開する

public class SampleController {
    @AuraEnabled
    public static void doSomething() {
        try {
            // 処理
        } catch (Exception e) {
            // ロールバックしてもイベントが公開される
            EventBus.publish(createLogEntryEvent(e));
            throw new AuraHandledException(e.getMessage());
        }
    }

    private static LogEntryEvent__e createLogEntryEvent(Exception e) {
        return new LogEntryEvent__e(
            Message__c = e.getMessage(),
            DetailMessage__c = e.getStackTraceString()
        );
    }
}

Appendix

プラットフォームイベントを公開するApexのテスト

下記の二通りあります。

  • Test.stopTest()の後にAssertメソッドを実行する
  • Test.getEventBus().deliver();の後にAssertメソッドを実行する
@IsTest
public class SampleControllerTest {
    @IsTest
    static void testDoSomething() {
        try {
            Test.startTest();
            SampleController.doSomething();
            Test.stopTest();
        } catch (Exception e) {
			Test.getEventBus().deliver();
            Assert.isInstanceOfType(e, AuraHandledException.class);
            List<Log__c> result = [SELECT Id FROM Log__c];
            Assert.areEqual(1, result.size(), 'ログサイズ');
        }
    }
}

Deliver Test Event Messages | Salesforce Developers

参考

3
2
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
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?