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
CTIT InsulationCTIT Insulation 

getting "Attempt to de-reference a null object" error when I try to promote a trigger & class

Hi All. I am trying to promote an Apex trigger, an Apex class, and an Apex test class. All work in sandbox environment, but when I try to validate during promotion to production, I get "Attempt to de-reference a null object" error, which points to the last line of code in the Apex class, which contains only the closing bracket. This was copied from a similar set of classes on another object, which is in production with no issues.

Here is the trigger:
trigger Contract_Triggers on Contract (after update) { //only runs after update

    set<id> ContractIds = new set<id>();

    if(trigger.isafter){
        if(trigger.isupdate){
            for(Contract c:trigger.new){
                if(c.Copy_Approval_Comments__c == true){
                    ContractIds.add(c.id);
                }
            }
        }
    }
    
    //calls @future class to ensure order of operation.
    if(ContractIds.size() > 0) {
        Contract_Approval_Comment_Handler.updateContractComment(ContractIds);
    }
        
}


Here is the Apex class:
public class Contract_Approval_Comment_Handler {
    @future
    public static void updateContractComment(set<id> cList){

        List<Contract> Contracts = [Select c.Id, c.Copy_Approval_Comments__c, c.Approval_Comments__c, (Select ActorId, Comments, CreatedDate From ProcessSteps order by CreatedDate) 
                             From 
                                 Contract c
                             where 
                                 c.Copy_Approval_Comments__c = True AND 
                                 c.id IN: cList];
            
        List<Contract> ContractsToUpdate = new List<Contract>(); //stores records to be updated
        
        //creates map of users that are active and non portal users 
        Map<ID, User> uMap = new Map<ID, User>([SELECT Id, Name FROM User WHERE IsActive =: true]);
        system.debug('User Map >>>>> ' + uMap);
        
        System.debug('******************************************** Contract = ' + Contracts);
        System.debug('******************************************** Size of Contract = ' + Contracts.size());
        
        if (Contracts.size()>0){
            for(Contract con: Contracts){
                if(con.ProcessSteps.size() >0){  
                    con.Approval_Comments__c = '';
                    for (ProcessInstanceHistory ps : con.ProcessSteps){
                        if (ps.Comments != null){
                            string username = uMap.get(ps.ActorId).name;   
                            con.Approval_Comments__c += '\n' + username + ': ' + ps.Comments;          
                             System.debug('*********************************************** Comments copied:' + ps.comments);
                         }
                     }
                     con.Copy_Approval_Comments__c =false;
                     ContractsToUpdate.add(con);
                 }
             }
        }
        
        if( ContractsToUpdate.size()> 0 ){
        
            Database.SaveResult[] srList = Database.update(ContractsToUpdate, false);
        
            // Iterate through each returned result
            for (Database.SaveResult sr : srList) {
                if (sr.isSuccess()) {
                    // Operation was successful, so get the ID of the record that was processed
                    System.debug('Successfully updated record ID: ' + sr.getId());
                } else {
                    // Operation failed, so get all errors                
                    for(Database.Error err : sr.getErrors()) {
                        System.debug('The following error has occurred.');                    
                        System.debug(err.getStatusCode() + ': ' + err.getMessage());
                    }
                }
            }
        }
    }    
}

And here is the test class:
@isTest(SeeAllData=True)
public class Contract_Approval_Comment_HandlerTest {
  static testMethod void run()

  {  List<Contract> Contracts = [Select c.Id, c.Copy_Approval_Comments__c From Contract c where c.Status = 'Activated' and c.Multiple_Trailers_at_this_location__c = False limit 100];
            
        List<Contract> ContractsToUpdate = new List<Contract>(); //stores records to be updated
        set<id> ContractIds = new set<id>();
             
        if (Contracts.size()>0){
            for(Contract con: Contracts){
                    con.Copy_Approval_Comments__c = True;
                    ContractsToUpdate.add(con);
                    ContractIDs.add(con.Id);
                }
             }
      
       if( ContractsToUpdate.size()> 0 ){
            Database.SaveResult[] srList = Database.update(ContractsToUpdate);
         }
   
   
       Test.startTest();     
            Contract_Approval_Comment_Handler.UpdateContractComment(ContractIds);    
       Test.stopTest();   
  }  
}
Any help will be greatly appreciated.

Thanks,
Stave A.
 
Best Answer chosen by CTIT Insulation
Thiruchuri AdityanThiruchuri Adityan
In the test class Line 24. Why do you need to explicitly again call method from helper class. Anyways that method is being called from the trigger and that trigger is being invoked because of your update statement..

All Answers

Thiruchuri AdityanThiruchuri Adityan
In the test class Line 24. Why do you need to explicitly again call method from helper class. Anyways that method is being called from the trigger and that trigger is being invoked because of your update statement..
This was selected as the best answer
CTIT InsulationCTIT Insulation
Thiruchuri,

  Thank you for the tip. I took the second call out and was able to promote the classes to production..

 
Thiruchuri AdityanThiruchuri Adityan
If my answer helped you, please mark it as the best answer
CTIT InsulationCTIT Insulation
Done. And thanks again!