- 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? |