- SalesforceChaCha
- Posts
- ๐ If at first you don't succeed ... ๐บ
๐ If at first you don't succeed ... ๐บ
... then implement a retry framework! ๐ฅ
Good morning, Salesforce Nerds! Do you know how healthy ๐ช your batch jobs are in your org(s)? ๐ค
Are there super-critical jobs that run overnight you rush to check the results of first thing in the morning? ๐
You know the drill โฆ ๐ทโโ๏ธ
Setup โถ๏ธ Environments โถ๏ธ Jobs โถ๏ธ Apex Jobs
Search feverously for overnight batch failures. ๐ฐ
Nooooooooooooo! ๐๏ธ There were a handful of failures! Time to put on that firefighting hat - there goes your morning plans. ๐ฅ๐งโ๐๐
Ugh, this sucks. Donโt get stuck in this cycle. ๐๐
Truth is, thereโs always going to be a reactionary element ๐ตโ๐ซ to building apps for our clients. ๐ฏ
One of our jobs as Technical Architects and Developers is to mitigate this as much as possible. ๐ง
Today weโre going to check out one way to do just that when it comes to handling exceptions in Batch Apex! ๐ชฃ

Agenda for today includes
If at first you donโt succeed โฆ
Daily Principle
All the Memes
If at first you donโt succeed โฆ
Today we will discuss -
๐ The problem ๐บ
๐ The solution ๐บ
๐ Show me the code ๐บ
๐ The Problem
First, letโs level ๐ set on what Batch Apex is โฆ
โฆ Batch Apex operates over small batches of records, covering your entire record set and breaking the processing down to manageable chunks โฆ
Basically - we can write code ๐ฅ๏ธ thatโs only job is to run specialized business logic against huge ๐ data sets - think hundreds of thousands or even millions of records! ๐ฅ
It does this by breaking down ๐๏ธ the overall data set into smaller chunks (aka batches)! ๐ฆ๏ธ
Hereโs a quick visual: ๐

do the thing on 500k records in batches of 2000 records at a time
This is a fairly standard Batch processing workflow. ๐ค
Got it? ๐๏ธ If you need a little more - no worries - just hit these up:
Issues arise when batches start to fail. โ
Remember, Batch Apex is a form of Asynchronous Apex. Ultimately, this means the batches run independently of one another. ๐
But, they can also fail independently of one another too! ๐
Meaning, in our example above โ๏ธ, itโs entirely possible for some of the batches to blow up. ๐ฅ
Giving us something like this: ๐๏ธ
Getting back to that mitigation thing โฆ ๐ค
These kinds of errors can be amongst the trickiest ๐ช to solve. Many times requiring analysis to:
Find the records that failed ๐๏ธ
Determine why they failed โ๏ธ
โFixโ the reason they failed ๐ ๏ธ
Re-run the business logic against the โfixedโ records โถ๏ธ
How can Architects and Developers solve for this? ๐งฉ
Turns out the mothership has provided a solution! ๐
๐ The Solution
Itโs actually pretty simple! ๐คฆ
Itโs just another interface! ๐ฅ
Youโve herd us tout the importance of these in the past. Weโve even discussed other interfaces native to the platform you can leverage.
This is no different.
From a developerโs perspective ๐ we just need to do 3 things:
Add this code your batch class declaration
implements Database.RaisesPlatformEvents
Add an after insert trigger to the BatchApexErrorEvent Platform Event
Process the data from the Platform Event in the trigger
Thatโs really it. ๐คท
Of course, the obtuse part here is what does โProcess the dataโ mean to you and your org? ๐ค
This is up to your business and should fit your needs. Typically, I see some variation of one or all of the following: ๐๏ธ
โ Log the exception in a custom object. Thereโs lots of useful data in the event record - reason for exception, the Idโs of the records being operated on in the batch, the full stack trace, and more!
โ Decorate the records that failed processing with something that will notify a user it failed. Maybe add a link to the error log record or something to the Account if it failed?
โ Write another batch class that will automatically retry execution on all the failed batches that your persisted in your Custom Object!
Pretty slick stuff if you ask me! ๐
โ No need to stress ๐ if your batches are failing!
โ No need to dig through the Setup UI ๐ to troubleshoot!
โ No need to analyze ๐งญ tons of data to figure out why batches are failing!
๐ค Show me the code
Like we said up top ๐๏ธ , devs just need to do 3 things.
Letโs see them in an example! ๐ Taken straight from the dev guide!
First, implement the interface in your batch class. ๐ป๏ธ This tells Salesforce to fire the Platform Event if an error happens during execution of this class:
public with sharing class YourSampleBatchJob implements Database.Batchable<SObject>,
Database.RaisesPlatformEvents{
// class implementation
}
Something to note โ๏ธ here. There are no methods to implement from this interface - itโs whatโs known as a marker interface.
Moving on โฆ ๐ฌ๏ธ
Next, create an after insert trigger on the BatchApexErrorEvent Platform Event like so and fill it in with your custom logic:
trigger MarkDirtyIfFail 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]
);
List<Account> records = 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
);
records.add(a);
}
}
}
update records;
}
Here weโre just pulling data off the error event and adding some details on the original record that failed. This is where you could also log the error for later processing, too.
Weโre skipping some best practices for brevity - in the real world you wouldnโt want your code inside your trigger! ๐ฏ
But, you can begin to see how useful this really is. ๐ฑ
This event provides all the data we need to track and take action on our Batch Apex failures! โ
So, now we can provide a full end-to-end batch solution that looks something like this: ๐ฅณ๐๐ฅณ

implement the interface, pull data off the error event in a trigger, do the needful
Do yourself and your clients a favor. ๐ Start planning to leverage this for any Batch Apex you implement!
Your client with love โค๏ธ it and youโre solution will be that much stronger! ๐งฑ
Daily Principle
"Never allow the same bug to bite you twice."
and now....Your Daily Memes



What did you think about today's newsletter? |