Sunday 5 April 2020

Firing Platform Events from Batch Apex

Hi ,

Here we are going to learn how to fire platform events when there is any unhandled exception occurred in start or execute or finish methods in batch apex.

Batch Apex classes can fire platform events when encountering an error or exception. Clients listening on an event can obtain actionable information, such as how often the event failed and which records were in scope at the time of failure. Events are also fired for Salesforce Platform internal errors and other uncatchable Apex exceptions such as LimitExceptions, which are caused by reaching governor limits.

An event message provides more granular error tracking than the Apex Jobs UI. It includes the record IDs being processed, exception type, exception message, and stack trace. We can also incorporate custom handling and retry logic for failures.

 We can invoke custom Apex logic from any trigger on this type of event, so Apex developers can build functionality like custom logging or automated retry handling.

Here "BatchApexErrorEvent" object  represents a platform event associated with a batch Apex class.

To fire a platform event, a batch Apex class declaration must implement the Database.RaisesPlatformEvents interface.

Eg:

public with sharing class AccountProcessing implements Database.Batchable<SObject>, 
   Database.RaisesPlatformEvents{ 
   // class implementation 
} 

We can listen the platform events through apex trigger or process builder or external system.

Apex Trigger on Platform event supports "after insert" event only.

Here we are going to the example with a trigger on platform event object "BatchApexErrorEvent"

Eg:

This example creates a trigger to determine which accounts failed in the batch transaction.

Custom field Dirty__c indicates that the account was one of a failing batch and ExceptionType__c indicates the exception that was encountered.

JobScope and ExceptionType are fields in the BatchApexErrorEvent object.



trigger UpdateAccountsonfailure on BatchApexErrorEvent (after insert) {
    Set<Id> asyncApexJobIdSet = new Set<Id>();
    for(BatchApexErrorEvent evt:Trigger.new){
        asyncApexJobIdSet.add(evt.AsyncApexJobId);
    }
    
    Map<Id,AsyncApexJob> jobs = new Map<Id,AsyncApexJob>(
        [SELECT id, ApexClass.Name FROM AsyncApexJob WHERE Id IN :asyncApexJobIdSet]
    );
    
    List<Account> accountList = new List<Account>();
    for(BatchApexErrorEvent evt:Trigger.new){
        //only handle events for the job(s) we care about
        if(jobs.get(evt.AsyncApexJobId).ApexClass.Name == 'AccountUpdaterJob'){
            for (String item : evt.JobScope.split(',')) {
                Account a = new Account(
                    Id = (Id)item,
                    ExceptionType__c = evt.ExceptionType,
                    Dirty__c = true
                );
                accountList.add(a);
            }
        }
    }
    update records;
}

Reference:

https://developer.salesforce.com/docs/atlas.en-us.224.0.platform_events.meta/platform_events/sforce_api_objects_batchapexerrorevent.htm

https://developer.salesforce.com/docs/atlas.en-us.224.0.apexcode.meta/apexcode/apex_batch_platformevents.htm?search_text=Database.RaisesPlatformEvents




1 comment:

  1. Thanks for sharing post. It is easy to understand how to Fire Platform Events from Batch Apex,usefull in salesforce services.
    Salesforce Integration Services

    ReplyDelete

How to include a screen flow in a Lightning Web Component

 Hi, Assume  you have a flow called "Quick Contact Creation" and API Name for the same is "Quick_Contact_Creation". To i...