In our org we are calling batches from an external system using salesforce API. When a batch is failing the external system create a bug and it goes into our standard processes.
A new requirement has made us create multiples batches which are called one atfer another in order to transfert ownership of a lot of records accross differents objects.
Each batch in the chain can tag the custom object WalletTranferRequest__c with an error and the last batch will update the request with an error status. (see code below)
public void finish(Database.BatchableContext BC){
String idWalletError = '';
List<WalletTransferRequest__c> listWtrFinalStatus = new List<WalletTransferRequest__c> ([SELECT Id, ErrorOnLead__c, ErrorOnOpportunity__c, ErrorOnContract__c, ErrorOnContact__c, ErrorOnSeizure__c, ErrorOnTask__c, ErrorOnEvent__c, ErrorOnCase__c, ErrorOnAccount__c, TransfertRealDate__c, Status__c FROM WalletTransferRequest__c WHERE Id IN: mapWt.keySet()]);
for(WalletTransferRequest__c wtr : listWtrFinalStatus){
wtr.TransfertRealDate__c = date.today();
if(wtr.ErrorOnLead__c || wtr.ErrorOnOpportunity__c || wtr.ErrorOnContract__c || wtr.ErrorOnContact__c || wtr.ErrorOnSeizure__c || wtr.ErrorOnTask__c || wtr.ErrorOnEvent__c || wtr.ErrorOnCase__c || wtr.ErrorOnAccount__c){
wtr.Status__c = 'Error';
idWalletError = idWalletError + wtr.Id + '; ';
}else{
wtr.Status__c = 'Validated';
}
}
List<Database.SaveResult> updateResults = Database.update(listWtrFinalStatus, false);
if(idWalletError != ''){
BatchWalletTransferException bwte = new BatchWalletTransferException('Erreur sur les demandes de transfert suivants: ' + idWalletError);
throw(bwte);
}
}
As said, we want to update the record with an error, but we need to send an exception to the external system or else it wont create a bug and the error wont be monitored automatically.
The thing is when I throw a custom exception the update of the record is rollback(ed?).
I know that when you throw uncatch exception there is a rollback, but is there a way to avoid that? I tried to put a allOrNone in the DML but it prevent just from firing exception not from rollback if there is one.
Will I be forced to do 2 transactions?