+ Start a Discussion
AbhishekJAbhishekJ 

Receiving System.NullPointerException: Attempt to de-reference a null object () error email.

I am receiving error email from ApexApplication <info@salesforce.com> with following content:
Subject: Developer script exception from ABC : ContactTrigger : ContactTrigger: execution of AfterUpdate  caused by: System.NullPointerException: Attempt to de-reference a null object  ()
Apex script unhandled trigger exception by user/organization: 

ContactTrigger: execution of AfterUpdate

caused by: System.NullPointerException: Attempt to de-reference a null object

Class.ContactTriggerHandler.onAfterUpdate: line 28, column 1
Trigger.ContactTrigger: line 15, column 1

Here is the Trigger:
trigger ContactTrigger on Contact (after insert, after update,after delete,after undelete) 
    
    if(Trigger.isAfter) {
            if(Trigger.isUpdate) {
            ContactTriggerHandler.onAfterUpdate(Trigger.new,Trigger.oldMap);
            }
            
            if(Trigger.isInsert){
             ContactTriggerHandler.OnAfterInsert(Trigger.new);
            }
            
            if(Trigger.IsDelete){
                ContactTriggerHandler.OnAfterDelete(Trigger.old);
            }
            
            if(Trigger.IsUnDelete){
                ContactTriggerHandler.OnUndelete(Trigger.new);
            }
    }
     
}

Here is apex class handler
public class ContactTriggerHandler {
    public static void onAfterUpdate(List<Contact> newContacts, Map<id,Contact> oldContacts) {
            updateSortedCorrespondencePreferneceData(newContacts,oldContacts);
            updateSalutationOnCommunicationContent(newContacts,oldContacts); 
            id cpCapitalPartnerRT = fetchRecordTypeId('Account','CP Capital Partner');
            List<Contact> newList = new List<Contact>();
            set<Id> oldAndNewAccountIds = new set<id>();
            for(Contact con : newContacts) {
                oldAndNewAccountIds.add(con.accountId);
                oldAndNewAccountIds.add(oldContacts.get(con.id).accountId);
            }
            Map<Id,Account> accountDetails = new Map<Id,Account>([Select Id,RecordTypeId from Account where Id in :oldAndNewAccountIds]);
            for(Contact con : newContacts) {
                    if(accountDetails !=NULL && con!= Null && con.accountId != oldContacts.get(con.Id).accountId  ) { 
                        if(  accountDetails.containsKey(con.accountId) && (accountDetails.get(con.accountId).recordTypeId == cpCapitalPartnerRT || accountDetails.get(oldContacts.get(con.Id).accountId).recordTypeId == cpCapitalPartnerRT) ) {
                            newList.add(con);
                        }
                    } else if(accountDetails !=NULL && con!= Null && accountDetails.get(con.accountId).recordTypeId == cpCapitalPartnerRT ) { 
                        newList.add(con);
                    }
            }        
            Email_InformationClass.getEmailTableData(newList,oldContacts); 
            updateCPIntralinksAccess(newContacts,oldContacts);
    }
    public static void OnAfterDelete(contact[] oldList){
        
        updateCPIntralinksAccess(oldList, null);
    }
     public static void OnAfterInsert(contact[] newList){
        
        updateCPIntralinksAccess(newList, null);
    }
    public static void OnUndelete(contact[] newList){ 
         
         updateCPIntralinksAccess(newList,null);
    }
    private static void updateSalutationOnCommunicationContent(List<Contact> newContacts, Map<id,Contact> oldContacts){
        set<id> contactsToProcess = new set<id>();
        for(Contact con : newContacts) {
            if((String.isNotBlank(con.email) && !con.email.contains('@test.com'))  && ((con.Seniority_Rank__c != oldContacts.get(con.Id).Seniority_Rank__c) ||
                                                                                                  (con.FirstName != oldContacts.get(con.id).FirstName)) || (con.International_Salutation_Type__c!= oldContacts.get(con.Id).International_Salutation_Type__c || String.isBlank(oldContacts.get(con.Id).email))
              )
            {
                        contactsToProcess.add(con.id);
            }
        }
        if(contactsToProcess.size() > 0) {
            List<Correspondence_Preference__c> corrPrefToProcess = new List<Correspondence_Preference__c>([Select Id, Company__c, RecordType.Name from Correspondence_Preference__c where Recipient_Type__c = 'To' AND Contact__c In :contactsToProcess]);
            set<string> cpNames = new Set<String>();
            set<string> accountNames = new Set<String>();
            for(Correspondence_Preference__c cp : corrPrefToProcess) {
                cpNames.add(cp.RecordType.Name);
                accountNames.add(cp.Company__c);
            }
            List<Communications_Content__c> ccList = new List<Communications_Content__c>([Select Id,Salutation__c,Company__c,Correspondence_Preference__c from Communications_Content__c where Company__c IN :accountNames AND Correspondence_Preference__c IN :cpNames]);
            CommunicationContentTriggerHandler handler = new CommunicationContentTriggerHandler(true,200,true);
            handler.updateSalutationField(null,ccList); 
        }
    private static void updateSortedCorrespondencePreferneceData(List<Contact> newContacts, Map<id,Contact> oldContacts) {
        set<id> contactsToProcess = new set<id>();
        for(Contact con : newContacts) {
            if((con.Seniority_Rank__c != oldContacts.get(con.Id).Seniority_Rank__c) ||
               (con.Email != oldContacts.get(con.id).Email)
              ) {
                  contactsToProcess.add(con.id);
              }
        }
        if(contactsToProcess.size() > 0) {
            List<Correspondence_Preference__c> corrPrefToProcess = new List<Correspondence_Preference__c>([Select Id, Commitment__c, RecordTypeId from Correspondence_Preference__c where Contact__c In :contactsToProcess]);
            
            CorrespondenceTriggerHandler.getCommRecTypeData(corrPrefToProcess,null,false);
        }
    }
    private static id fetchRecordTypeId(string sObj, string rt) {
        System.debug('fetch params>>'+sObj + '<<<rt>>>'+rt);
        String recordtypeId = Schema.getGlobalDescribe().get(sObj).getDescribe().getRecordTypeInfosByName().get(rt).getRecordTypeId(); 
        return Schema.getGlobalDescribe().get(sObj).getDescribe().getRecordTypeInfosByName().get(rt).getRecordTypeId();
    }
    public static void updateCPIntralinksAccess(List<Contact> newContacts, Map<id,Contact> OldMap){
        Map<ID,List<contact>> mapConWithAcc = new Map<ID,List<contact>>();
        List<account> accList = new List<account>();
        String temp= '';
        Map<Id,String> accUpdateMap = new Map<Id,String>();
        Set<ID> accid = new Set<ID>();
        for(contact con: newContacts){
            if(oldMap == null || oldMap.get(con.id).CP_Intralinks_Access__c != con.CP_Intralinks_Access__c ){ 
                accid.add(con.accountid); 
            }
        }
        for(Account acc : [Select id,CP_Intralinks_Access__c,(Select id,CP_Intralinks_Access__c,accountid from contacts) from account where id in :accid]) {
            set<string> val = new set<string>();
            String finalVal = '' ;
            for(Contact ct : acc.contacts) {
                if(String.isNOtBlank(ct.CP_Intralinks_Access__c)) {
                }
            }
            List<String> valList = new List<String>();
            valList.addAll(val);
            if(valList.size() > 0) {
                finalVal = String.join(valList,',');
            }
            acc.CP_Intralinks_Access__c = finalVal ;
            accList.add(acc);
        }
        if(accList.size() > 0) {
            update accList ;
        }
    }
}


 
Best Answer chosen by AbhishekJ
SATHISH REDDY.SATHISH REDDY.
trigger ContactTrigger on Contact (after insert, after update,after delete,after undelete) 
    
    if(Trigger.isAfter) {
            if(Trigger.isUpdate) {
            ContactTriggerHandler.onAfterUpdate(Trigger.new,Trigger.oldMap);
            }
            
            if(Trigger.isInsert){
             ContactTriggerHandler.OnAfterInsert(Trigger.new);
            }
            //Change this block from Trigger.Old to Trigger.OldMap
            if(Trigger.IsDelete){
                ContactTriggerHandler.OnAfterDelete(Trigger.oldMap);
            }
            
            if(Trigger.IsUnDelete){
                ContactTriggerHandler.OnUndelete(Trigger.new);
            }
    }
     
}

//Handler Logic

public class ContactTriggerHandler {
    public static void onAfterUpdate(List<Contact> newContacts, Map<id,Contact> oldContacts) {
            updateSortedCorrespondencePreferneceData(newContacts,oldContacts);
            updateSalutationOnCommunicationContent(newContacts,oldContacts); 
            id cpCapitalPartnerRT = fetchRecordTypeId('Account','CP Capital Partner');
            List<Contact> newList = new List<Contact>();
            set<Id> oldAndNewAccountIds = new set<id>();
            for(Contact con : newContacts) {
                oldAndNewAccountIds.add(con.accountId);
                oldAndNewAccountIds.add(oldContacts.get(con.id).accountId);
            }
            Map<Id,Account> accountDetails = new Map<Id,Account>([Select Id,RecordTypeId from Account where Id in :oldAndNewAccountIds]);
            for(Contact con : newContacts) {
                    if(accountDetails !=NULL && con!= Null && con.accountId != oldContacts.get(con.Id).accountId  ) { 
                        if(  accountDetails.containsKey(con.accountId) && (accountDetails.get(con.accountId).recordTypeId == cpCapitalPartnerRT || accountDetails.get(oldContacts.get(con.Id).accountId).recordTypeId == cpCapitalPartnerRT) ) {
                            newList.add(con);
                        }
                    } else if(accountDetails !=NULL && con!= Null && accountDetails.get(con.accountId).recordTypeId == cpCapitalPartnerRT ) { 
                        newList.add(con);
                    }
            }        
            Email_InformationClass.getEmailTableData(newList,oldContacts); 
            updateCPIntralinksAccess(newContacts,oldContacts);
    }
    //Changed it from OldList to OldMap
    public static void OnAfterDelete(cMap<Id,Contact> oldMap){
        
        updateCPIntralinksAccess(null, oldMap);
    }
     public static void OnAfterInsert(contact[] newList){
        
        updateCPIntralinksAccess(newList, null);
    }
    public static void OnUndelete(contact[] newList){ 
         
         updateCPIntralinksAccess(newList,null);
    }
    private static void updateSalutationOnCommunicationContent(List<Contact> newContacts, Map<id,Contact> oldContacts){
        set<id> contactsToProcess = new set<id>();
        for(Contact con : newContacts) {
            if((String.isNotBlank(con.email) && !con.email.contains('@test.com'))  && ((con.Seniority_Rank__c != oldContacts.get(con.Id).Seniority_Rank__c) ||
                                                                                                  (con.FirstName != oldContacts.get(con.id).FirstName)) || (con.International_Salutation_Type__c!= oldContacts.get(con.Id).International_Salutation_Type__c || String.isBlank(oldContacts.get(con.Id).email))
              )
            {
                        contactsToProcess.add(con.id);
            }
        }
        if(contactsToProcess.size() > 0) {
            List<Correspondence_Preference__c> corrPrefToProcess = new List<Correspondence_Preference__c>([Select Id, Company__c, RecordType.Name from Correspondence_Preference__c where Recipient_Type__c = 'To' AND Contact__c In :contactsToProcess]);
            set<string> cpNames = new Set<String>();
            set<string> accountNames = new Set<String>();
            for(Correspondence_Preference__c cp : corrPrefToProcess) {
                cpNames.add(cp.RecordType.Name);
                accountNames.add(cp.Company__c);
            }
            List<Communications_Content__c> ccList = new List<Communications_Content__c>([Select Id,Salutation__c,Company__c,Correspondence_Preference__c from Communications_Content__c where Company__c IN :accountNames AND Correspondence_Preference__c IN :cpNames]);
            CommunicationContentTriggerHandler handler = new CommunicationContentTriggerHandler(true,200,true);
            handler.updateSalutationField(null,ccList); 
        }
    private static void updateSortedCorrespondencePreferneceData(List<Contact> newContacts, Map<id,Contact> oldContacts) {
        set<id> contactsToProcess = new set<id>();
        for(Contact con : newContacts) {
            if((con.Seniority_Rank__c != oldContacts.get(con.Id).Seniority_Rank__c) ||
               (con.Email != oldContacts.get(con.id).Email)
              ) {
                  contactsToProcess.add(con.id);
              }
        }
        if(contactsToProcess.size() > 0) {
            List<Correspondence_Preference__c> corrPrefToProcess = new List<Correspondence_Preference__c>([Select Id, Commitment__c, RecordTypeId from Correspondence_Preference__c where Contact__c In :contactsToProcess]);
            
            CorrespondenceTriggerHandler.getCommRecTypeData(corrPrefToProcess,null,false);
        }
    }
    private static id fetchRecordTypeId(string sObj, string rt) {
        System.debug('fetch params>>'+sObj + '<<<rt>>>'+rt);
        String recordtypeId = Schema.getGlobalDescribe().get(sObj).getDescribe().getRecordTypeInfosByName().get(rt).getRecordTypeId(); 
        return Schema.getGlobalDescribe().get(sObj).getDescribe().getRecordTypeInfosByName().get(rt).getRecordTypeId();
    }
    public static void updateCPIntralinksAccess(List<Contact> newContacts, Map<id,Contact> OldMap){
        Map<ID,List<contact>> mapConWithAcc = new Map<ID,List<contact>>();
        List<account> accList = new List<account>();
        String temp= '';
        Map<Id,String> accUpdateMap = new Map<Id,String>();
        Set<ID> accid = new Set<ID>();
       
//Added below else block
 if(!newContacts.isEmpty() && newContacts != null){       
            for(contact con: newContacts){
                if(oldMap == null || oldMap.get(con.id).CP_Intralinks_Access__c != con.CP_Intralinks_Access__c ){ 
                    accid.add(con.accountid); 
                }
            }
        }else if(OldMap != null && !OldMap.isEmpty()){
            for(Id conId: OldMap.keyset()){
                //After Delete Logic goes here;
                accId.add('Add the records');
                }
            }
        }
        for(Account acc : [Select id,CP_Intralinks_Access__c,(Select id,CP_Intralinks_Access__c,accountid from contacts) from account where id in :accid]) {
            set<string> val = new set<string>();
            String finalVal = '' ;
            for(Contact ct : acc.contacts) {
                if(String.isNOtBlank(ct.CP_Intralinks_Access__c)) {
                }
            }
            List<String> valList = new List<String>();
            valList.addAll(val);
            if(valList.size() > 0) {
                finalVal = String.join(valList,',');
            }
            acc.CP_Intralinks_Access__c = finalVal ;
            accList.add(acc);
        }
        if(accList.size() > 0) {
            update accList ;
        }
    }
}

Hi there,

Looks like your input arguments are incorrect for afterdelete and i did tweak a bit of your logic under updateCPIntralinksAccess method. Please go through and let me know if you have any questions.

Please mark it as resolved if this helps. Cheers!

All Answers

SATHISH REDDY.SATHISH REDDY.
trigger ContactTrigger on Contact (after insert, after update,after delete,after undelete) 
    
    if(Trigger.isAfter) {
            if(Trigger.isUpdate) {
            ContactTriggerHandler.onAfterUpdate(Trigger.new,Trigger.oldMap);
            }
            
            if(Trigger.isInsert){
             ContactTriggerHandler.OnAfterInsert(Trigger.new);
            }
            //Change this block from Trigger.Old to Trigger.OldMap
            if(Trigger.IsDelete){
                ContactTriggerHandler.OnAfterDelete(Trigger.oldMap);
            }
            
            if(Trigger.IsUnDelete){
                ContactTriggerHandler.OnUndelete(Trigger.new);
            }
    }
     
}

//Handler Logic

public class ContactTriggerHandler {
    public static void onAfterUpdate(List<Contact> newContacts, Map<id,Contact> oldContacts) {
            updateSortedCorrespondencePreferneceData(newContacts,oldContacts);
            updateSalutationOnCommunicationContent(newContacts,oldContacts); 
            id cpCapitalPartnerRT = fetchRecordTypeId('Account','CP Capital Partner');
            List<Contact> newList = new List<Contact>();
            set<Id> oldAndNewAccountIds = new set<id>();
            for(Contact con : newContacts) {
                oldAndNewAccountIds.add(con.accountId);
                oldAndNewAccountIds.add(oldContacts.get(con.id).accountId);
            }
            Map<Id,Account> accountDetails = new Map<Id,Account>([Select Id,RecordTypeId from Account where Id in :oldAndNewAccountIds]);
            for(Contact con : newContacts) {
                    if(accountDetails !=NULL && con!= Null && con.accountId != oldContacts.get(con.Id).accountId  ) { 
                        if(  accountDetails.containsKey(con.accountId) && (accountDetails.get(con.accountId).recordTypeId == cpCapitalPartnerRT || accountDetails.get(oldContacts.get(con.Id).accountId).recordTypeId == cpCapitalPartnerRT) ) {
                            newList.add(con);
                        }
                    } else if(accountDetails !=NULL && con!= Null && accountDetails.get(con.accountId).recordTypeId == cpCapitalPartnerRT ) { 
                        newList.add(con);
                    }
            }        
            Email_InformationClass.getEmailTableData(newList,oldContacts); 
            updateCPIntralinksAccess(newContacts,oldContacts);
    }
    //Changed it from OldList to OldMap
    public static void OnAfterDelete(cMap<Id,Contact> oldMap){
        
        updateCPIntralinksAccess(null, oldMap);
    }
     public static void OnAfterInsert(contact[] newList){
        
        updateCPIntralinksAccess(newList, null);
    }
    public static void OnUndelete(contact[] newList){ 
         
         updateCPIntralinksAccess(newList,null);
    }
    private static void updateSalutationOnCommunicationContent(List<Contact> newContacts, Map<id,Contact> oldContacts){
        set<id> contactsToProcess = new set<id>();
        for(Contact con : newContacts) {
            if((String.isNotBlank(con.email) && !con.email.contains('@test.com'))  && ((con.Seniority_Rank__c != oldContacts.get(con.Id).Seniority_Rank__c) ||
                                                                                                  (con.FirstName != oldContacts.get(con.id).FirstName)) || (con.International_Salutation_Type__c!= oldContacts.get(con.Id).International_Salutation_Type__c || String.isBlank(oldContacts.get(con.Id).email))
              )
            {
                        contactsToProcess.add(con.id);
            }
        }
        if(contactsToProcess.size() > 0) {
            List<Correspondence_Preference__c> corrPrefToProcess = new List<Correspondence_Preference__c>([Select Id, Company__c, RecordType.Name from Correspondence_Preference__c where Recipient_Type__c = 'To' AND Contact__c In :contactsToProcess]);
            set<string> cpNames = new Set<String>();
            set<string> accountNames = new Set<String>();
            for(Correspondence_Preference__c cp : corrPrefToProcess) {
                cpNames.add(cp.RecordType.Name);
                accountNames.add(cp.Company__c);
            }
            List<Communications_Content__c> ccList = new List<Communications_Content__c>([Select Id,Salutation__c,Company__c,Correspondence_Preference__c from Communications_Content__c where Company__c IN :accountNames AND Correspondence_Preference__c IN :cpNames]);
            CommunicationContentTriggerHandler handler = new CommunicationContentTriggerHandler(true,200,true);
            handler.updateSalutationField(null,ccList); 
        }
    private static void updateSortedCorrespondencePreferneceData(List<Contact> newContacts, Map<id,Contact> oldContacts) {
        set<id> contactsToProcess = new set<id>();
        for(Contact con : newContacts) {
            if((con.Seniority_Rank__c != oldContacts.get(con.Id).Seniority_Rank__c) ||
               (con.Email != oldContacts.get(con.id).Email)
              ) {
                  contactsToProcess.add(con.id);
              }
        }
        if(contactsToProcess.size() > 0) {
            List<Correspondence_Preference__c> corrPrefToProcess = new List<Correspondence_Preference__c>([Select Id, Commitment__c, RecordTypeId from Correspondence_Preference__c where Contact__c In :contactsToProcess]);
            
            CorrespondenceTriggerHandler.getCommRecTypeData(corrPrefToProcess,null,false);
        }
    }
    private static id fetchRecordTypeId(string sObj, string rt) {
        System.debug('fetch params>>'+sObj + '<<<rt>>>'+rt);
        String recordtypeId = Schema.getGlobalDescribe().get(sObj).getDescribe().getRecordTypeInfosByName().get(rt).getRecordTypeId(); 
        return Schema.getGlobalDescribe().get(sObj).getDescribe().getRecordTypeInfosByName().get(rt).getRecordTypeId();
    }
    public static void updateCPIntralinksAccess(List<Contact> newContacts, Map<id,Contact> OldMap){
        Map<ID,List<contact>> mapConWithAcc = new Map<ID,List<contact>>();
        List<account> accList = new List<account>();
        String temp= '';
        Map<Id,String> accUpdateMap = new Map<Id,String>();
        Set<ID> accid = new Set<ID>();
       
//Added below else block
 if(!newContacts.isEmpty() && newContacts != null){       
            for(contact con: newContacts){
                if(oldMap == null || oldMap.get(con.id).CP_Intralinks_Access__c != con.CP_Intralinks_Access__c ){ 
                    accid.add(con.accountid); 
                }
            }
        }else if(OldMap != null && !OldMap.isEmpty()){
            for(Id conId: OldMap.keyset()){
                //After Delete Logic goes here;
                accId.add('Add the records');
                }
            }
        }
        for(Account acc : [Select id,CP_Intralinks_Access__c,(Select id,CP_Intralinks_Access__c,accountid from contacts) from account where id in :accid]) {
            set<string> val = new set<string>();
            String finalVal = '' ;
            for(Contact ct : acc.contacts) {
                if(String.isNOtBlank(ct.CP_Intralinks_Access__c)) {
                }
            }
            List<String> valList = new List<String>();
            valList.addAll(val);
            if(valList.size() > 0) {
                finalVal = String.join(valList,',');
            }
            acc.CP_Intralinks_Access__c = finalVal ;
            accList.add(acc);
        }
        if(accList.size() > 0) {
            update accList ;
        }
    }
}

Hi there,

Looks like your input arguments are incorrect for afterdelete and i did tweak a bit of your logic under updateCPIntralinksAccess method. Please go through and let me know if you have any questions.

Please mark it as resolved if this helps. Cheers!
This was selected as the best answer
AbhishekJAbhishekJ
Thanks Satish, I will test this out and let you know.
AbhishekJAbhishekJ
Hey Satish,
I got this error while trying to update the trigger:
Error: Compile Error: Method does not exist or incorrect signature: void OnAfterDelete(Map<Id,Contact>) from the type ContactTriggerHandler at line 22 column 35
Could you please help.
Abhishek