I think you can acheive it by exception handling and just send the message in catch block.
public void execute(Database.BatchableContext info, List<sObject> scope)
{
try
{
//code
//code
}
Catch(Exception e)
{
List<User> user= new List<User>();
user = [select id,name,FirstName,email from user where Id IN :userid ];
if(user.size()>0)
{
List<Messaging.SingleEmailMessage> sendemailtouser = new List<Messaging.SingleEmailMessage>();
//retrive all user
for(User u : user)
{
//set subject in email
String subject='Deployment Status';
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
//set target object id
mail.setTargetObjectId(u.id);
mail.setSubject(subject); // Set the subject
mail.setSaveAsActivity(false);
mail.setPlainTextBody(u.FirstName);
//Add all email in List
sendemailtouser.add(mail);
}
if(sendemailtouser!=null && sendemailtouser.size()>0)
{
//Send email to user and result store here
Messaging.SendEmailResult[] results = Messaging.sendEmail(sendemailtouser);
}
}
}
}
You can capture your logs and still have individual batches fail and rollback. For that you need to define an instance variable in your batch class - List of custom object used for logging - to store your logs while batch is running and insert them all at once in the finish() method. You will have to add Database.Stateful to your class definition (see 'Using State in Batch Apex' in this document) to ensure that your instance variable is preserved across transactions.
lobal class TestBatch implements Database.Batchable<sObject>, Database.Stateful {
global List<Log__c> logs;
global TestBatch() {
logs = new List<Log__c>();
}
global Database.QueryLocator start(Database.BatchableContext BC) {
query = 'Your query...';
return Database.getQueryLocator(query);
}
global void execute(Database.BatchableContext BC, List<sObject> scope) {
for (sobject s : scope) {
try{
Your logic goes here...
} catch (Exception e) {
logs.add(new Log__c(
Name__c = '...',
Stacktrace__c = e.getStackTraceString()
));
throw e;
}
}
update scope;
}
global void finish(Database.BatchableContext BC) {
insert logs;
}
}
Important : If this is what you were looking for then please mark it as a "SOLUTION" or You can Click on the "Like" Button if this was beneficial for you.
You can capture your logs and still have individual batches fail and rollback. For that you need to define an instance variable in your batch class - List of custom object used for logging - to store your logs while batch is running and insert them all at once in the finish() method. You will have to add Database.Stateful to your class definition (see 'Using State in Batch Apex' in this document) to ensure that your instance variable is preserved across transactions.
Important :
If this is what you were looking for then please mark it as a "SOLUTION" or You can Click on the "Like" Button if this was beneficial for you.