function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
slxdeveloperslxdeveloper 

Batch Apex Error Handling

Trying to figure out how I can prevent roll-back on Apex Batches for a Scheduled Class and then capture the id's and messages for the records that fail in an update call and email that out to an admin.  Documentation doesn't seem clear on this.

FromCRMWonderlandFromCRMWonderland
Please refer following example from apex guide --- ( I guess this should work for you) Account myAcct = [select id, name, billingcity from account limit 1]; myAcct.billingcity = 'San Francisco'; Database.SaveResult SR = database.update(myAcct); for(Database.Error err: SR.getErrors()) { // process any errors here } ------ alok
slxdeveloperslxdeveloper

This needs to work in a scheduled (Batch) apex class.  So we're not talking about doing a single record update here.  Here is the code exerpt I have from my execute class:

 

 

Database.SaveResult[] lsr = Database.update(accountstoUpd);
for (Database.SaveResult SR : lsr) {
     if (!SR.isSuccess()) {
// need to capture the record id that failed to pass back in an email to the admin;
}
}

 

The Apex logs are showing the error happening but I need to be able to capture all id's that are failing and email those out.

 

slxdeveloperslxdeveloper

ok ... got it figured out, although I'm wondering if there is a way to capture this without having to save the errors into an object for passing back into the finish class for the batch.  Here's the snippet now:

 

 

if (accountstoUpd.size() > 0) {
     Database.SaveResult[] lsr = Database.update(accountstoUpd,false);
     Integer recordid = 0;
     for (Database.SaveResult SR : lsr) {
	if (!SR.isSuccess()) {
	this.errormsgs += 'Account Record:' + accountstoUpd[recordid].id + ', ' + SR.getErrors()[0].getMessage() + '<br/>';
	}
	recordid++;
     }
}
if (this.errormsgs.length() > 0) {
	ErrorLogs__c errtoSave = new ErrorLogs__c(details__c = this.errormsgs);
	insert errtoSave;
}

 

Then in the finish class I retrieve the errorlogs records to post into an email message for sending.

 

 

saasraysaasray

I know this is a few weeks old now but I had the same problem and this helped me with part of the solution but I also have a solution for the point about capturing the error messages:


although I'm wondering if there is a way to capture this without having to save the errors into an object for passing back into the finish class for the batch. 

 

 


 

You can keep a global string containing all of the messages as they build up. To make sure that the content of the string persists accross multiple batches you implement "Database.stateful" which is simply a case of adding it to your class definition for the batch process e.g.

 

global class myStatefulBatchProcess implements Database.Batchable<SObject>, Database.Stateful{

global String errorMsgs = '';

global void execute(Database.BatchableContext bc, List<sObject> scope)
{
...
errorMsgs += 'some error information\n';
...
}

global void finish(Database.BatchableContext bc)
{
//in the finish method the errorMsgs string contains all messages
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
...
mail.setPlainTextBody(errorMsgs );
}
}

 

 

sandeep@Salesforcesandeep@Salesforce

it is automatically handeled by Salesforce that if any batch meets exception then that record will be rolled back of that batch.