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
Nick MilsnerNick Milsner 

Before Insert Trigger Doesn't Seem to be Firing

Hi everyone, 

I'm writing a handler class called via a before insert trigger to prevent leads from getting created if they have a matching email across standard objects (account, contact, and lead). When I test my code in the anonymous window, I'm using an email that is planted across the three objects. Although my end goal is to prevent the creation of a lead if a matching email is found, I'm having trouble even seeing results in the debug log of parameters passed into my System methods. It would be super helpful if a member of this community can review my code and let me know where you think there are any holes and why it may be that my trigger and class aren't working properly. Thank you in advance! 
trigger MasterLeadTrigger on Lead (before insert, before update, before
    delete, after insert, after update, after delete,  after undelete) {
        
        List<Lead> newList = Trigger.new;
        
        MasterLeadTriggerHandler handler = new MasterLeadTriggerHandler();
        
		if(Trigger.isInsert && Trigger.isBefore){
            handler.OnBeforeInsert(Trigger.new);
        }
}

public class MasterLeadTriggerHandler {
    public void OnBeforeInsert(List<Lead> listNew){
        if(listNew.isEmpty()){
            System.debug('List is empty');
        }else{
            System.debug(listNew.size());
        }
        Set<String> email = new Set<String>();
        for(Lead newLead : listNew){
            if(newLead.Email != null){
                email.add(newLead.Email);
                System.assertEquals(email.size(),1);
            }
        }
        List<Lead> dupeLead = [SELECT Id FROM Lead WHERE Email IN :email 
                              OR Secondary_Email__c IN :email
                              OR Additional_Email__c IN :email];
        for(Lead newLead : listNew){
            if(dupeLead.size()>0){
                newLead.addError('This is a duplicate: '+dupeLead[0].Id);
            } update newLead;
        }
	}
}

 
Maharajan CMaharajan C
Hi Nick,

Remove the update statement at line No:  33  then try.

update newLead; // Remove this line and try

Thanks,
Maharajan.C
SUCHARITA MONDALSUCHARITA MONDAL

Hi Nick,

Please check with the following code. 

trigger LeadTrigger on Lead (before Insert, Before Update) {
        Set<String> email = new Set<String>();
        Set<String> setOfUniqueEmail = new Set<String>();        
            for(Lead ld : Trigger.New){
                if(ld.email!=null)
                    email.add(ld.Email);
            }
        for(Lead ld:[SELECT Email FROM Lead WHERE Email IN :email 
                                    OR Secondary_Email__c IN :email]){
                setOfUniqueEmail.add(ld.Email);
            }
            
            //check the  for duplicates
        for(Lead ld: Trigger.new){
                if(setOfUniqueEmail.contains(ld.Email)){
                    ld.adderror('Duplicate email found');
                }
               
           }
}

Share your thoughts!

Thanks,
Sucharita

Maharajan CMaharajan C
Hi Nick,

If you are using the Update Statement surely you will get an exception because you are performing the DML directly in the listNew(which is copy of Trigger.New).

In the before transaction you can overide or validate(using addError) the current record(Lead Record here) with out any DML Statements.

 And your Apex class code also needs refactoring:
 
public class MasterLeadTriggerHandler {
    public void OnBeforeInsert(List<Lead> listNew){
        
        Set<String> emailSet = new Set<String>();
        Map<String,Id> leadMap = new Map<String,Id>();
        for(Lead ld : listNew){
            if(ld.email!=null)
                emailSet.add(ld.Email);
        }
        for(Lead ld:[SELECT Email,Secondary_Email__c,Additional_Email__c FROM Lead WHERE Email IN :emailSet OR Secondary_Email__c IN :emailSet OR Additional_Email__c IN :emailSet]){
            if(!leadMap.containsKey(ld.Email) && ld.Email!=null)
            leadMap.put(ld.Email,ld.Id);
            if(!leadMap.containsKey(ld.Secondary_Email__c) && ld.Secondary_Email__c!=null)
            leadMap.put(ld.Secondary_Email__c,ld.Id);
            if(!leadMap.containsKey(ld.Additional_Email__c) && ld.Additional_Email__c != null)
            leadMap.put(ld.Additional_Email__c,ld.Id);
        }
        
        //check the  for duplicates
        for(Lead ld: listNew){
            if(leadMap.containsKey(ld.Email))
            {
                ld.adderror('This is a duplicate:  ' + leadMap.get(ld.Email));
            }
            
        }
        
    }
}

Thanks,
Maharajan.C
Nick MilsnerNick Milsner
Hi Maharajan, 

Thanks for the reply and refactoring. What I can't seem to wrap my head around is why the contents of the collection won't appear in my debug log when I attempt to insert a new lead with an email address. This gives me reason to belive that the trigger isn't firing. Do you have any thoughts? 
public class MasterLeadTriggerHandler {
    public void OnBeforeInsert(List<Lead> listNew){
        
        Set<String> emailSet = new Set<String>();
        Map<String,Id> leadMap = new Map<String,Id>();
        for(Lead ld : listNew){
            if(ld.email!=null)
                emailSet.add(ld.Email);      
        }
        System.debug(emailSet);

 
Nick MilsnerNick Milsner
Turns out my Apex Trigger was set to inactive. I went to Setup --> Custom Code --> Apex Triggers --> isActive = True. Welp, I'm going to try to shake this one off. Thank you all for your help!