No Retry Logic on External API Calls
“External APIs fail. Your integration should expect that.”
What Happened
Built a nightly batch sync between Salesforce and a client's ERP. Worked perfectly for three weeks. Then the ERP had a 2-minute maintenance window at exactly the wrong time. My batch just... failed silently. No retry. No alert. 400 records went unsynced and nobody noticed for a week until the finance team asked why invoices weren't matching.
The Wrong Way
public class ERPSyncBatch implements Database.Batchable<SObject>, Database.AllowsCallouts {
public void execute(Database.BatchableContext bc, List<Account> scope) {
for (Account acc : scope) {
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:ERP/accounts');
req.setMethod('POST');
req.setBody(JSON.serialize(acc));
HttpResponse res = new Http().send(req);
// If this fails? Too bad. Gone forever.
}
}
}The Right Way
public class ERPSyncBatch implements Database.Batchable<SObject>, Database.AllowsCallouts {
public void execute(Database.BatchableContext bc, List<Account> scope) {
List<Integration_Log__c> logs = new List<Integration_Log__c>();
for (Account acc : scope) {
HttpResponse res;
Integer retries = 0;
Boolean success = false;
while (retries < 3 && !success) {
try {
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:ERP/accounts');
req.setMethod('POST');
req.setBody(JSON.serialize(acc));
req.setTimeout(30000);
res = new Http().send(req);
success = (res.getStatusCode() == 200);
} catch (Exception e) {
retries++;
}
}
logs.add(new Integration_Log__c(
Record_Id__c = acc.Id,
Status__c = success ? 'Success' : 'Failed',
Retry_Count__c = retries,
Response__c = res?.getBody()?.left(32000)
));
}
insert logs;
}
}The Lesson
Log everything. Retry failures. Alert on persistent errors. Integrations are not set-and-forget.
Enjoyed this? Get more like it.
Glen's Musings — AI, investing, and building things. Occasional. Free.
More Integration Mistakes
Making a Callout from a Trigger
You cannot make HTTP callouts from a synchronous trigger context. Period.
Read moreCareer-EndingHardcoding API Credentials Instead of Using Named Credentials
Hardcoded API keys in Apex are a security audit's worst nightmare.
Read morePainfulPublishing Platform Events Without Error Handling
Platform Events can fail to publish. If you don't check, you'll never know.
Read more