I have been reading up on the custom logging, DML, and exceptions but haven't seen anything that talks about @Future methods and exceptions.
I have two scenarios:
- A Button is clicked on a Lead, class A is called (class A has a try/catch with logging), a Webservice class is called, the Webservice fails, an exception is thrown, the exception trickles back up to class A, logging class is called, and a new logging record is inserted.
- A Lead is inserted, a Trigger is fired, a Webservice is called from a future method, the Webservice fails, an exception is thrown.
- I want to put logging on the Trigger but because of the future method, the exception does not make it's way back up to the root level. I have found that if I want to log the exception, then I have to put the log on the
future method
. This breaks my pattern of always putting logging on the root level.
- I want to put logging on the Trigger but because of the future method, the exception does not make it's way back up to the root level. I have found that if I want to log the exception, then I have to put the log on the
Is there a way to push the exception up from a @future method
to the method or class that calls it? Is there a way to put logging on the root class in all scenarios even if there is a @future method
involved?
trigger AllLeadTrigger on Lead (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
if( Trigger.isInsert ){
if(Trigger.isBefore) {
...
}else {
...
}
}else if (Trigger.isUpdate ) {
if(Trigger.isBefore) {
...
}else {
try{
LeadEncryptedEmailStringCreation les = new LeadEncryptedEmailStringCreation();
les.leadEncryptedEmailStringCreate(Trigger.newMap, Trigger.oldMap);
}catch(Exception ex){
NFLogger.logError('AllLeadTrigger, LeadEncryptedEmailStringCreation, trigger', 'Call to leadEncryptedEmailStringCreate failed.', ex);
}
}
}
}
public with sharing class LeadEncryptedEmailStringCreation {
public void leadEncryptedEmailStringCreate(Map<Id, Lead> newLeads, Map<Id, Lead> oldLeads) {
List<Id> leadIDList = new List<Id>();
try {
for (Lead l : [SELECT Id, pi__url__c, IsConverted, Web_Id_NatFund__c, Encrypted_Email_String__c FROM Lead
WHERE Id IN :newLeads.keySet() AND pi__url__c != NULL AND IsConverted = FALSE AND Web_Id_NatFund__c != NULL
AND Encrypted_Email_String__c = NULL]) {
if (l.pi__url__c != oldLeads.get(l.id).pi__url__c) {
leadIDList.add(l.Id);
}
}
if (leadIDList.size() > 0) {
updateEncryptedEmailStringForLeads(leadIDList);
}
} catch (Exception e) {
throw e;
}
}
@Future(callout=true)
public static void updateEncryptedEmailStringForLeads(List<Id> leadIdList) {
try {
Map<String, String> idAndTokenMap = new Map<String, String>();
List<Lead> leadListUpdate = new List<Lead>();
TokenGenerator tg = new TokenGenerator();
idAndTokenMap = tg.getTokenizedPayloadForBulkLeads(leadIdList); //webservice is called here
for (String leadId : idAndTokenMap.keySet()) {
Lead l = new Lead(Id = leadId, Encrypted_Email_String__c = idAndTokenMap.get(leadId));
leadListUpdate.add(l);
}
update leadListUpdate;
}catch (Exception e) {
//throw e //this does persist upwards so I log here
NFLogger.logError('LeadEncryptedEmailStringCreation, tokenizer', 'There has been an error in the updateEncryptedEmailStringForLeads on Lead(s): ' + leadIdList, e);
}
}
}