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
Eric BlaxtonEric Blaxton 

How do I stop processing of After Insert Trigger if error found in Before Insert Trigger

Hi and thanks for your help.

I have 2 custom objects:
• Registrations
•  Registration Requests
The Problem: When the Registration Request Before Insert Trigger catches a duplicate it doesn’t stop the After Insert Trigger from running.  What is the best way to stop the processing of the After Insert Trigger if the error message is thrown in the Before Insert Trigger?
Registrations Object has this trigger to stop duplicates from being entered and a way to bypass it if decided:


trigger stopDupsonRegistrations on Registration__c (before insert) {
    Map<String, Registration__c> regMap = new Map<String, Registration__c>();
    Map<String, Registration__c> regMap1 = new Map<String, Registration__c>();
    Map<Boolean, Registration__c> regMap2 = new Map<Boolean, Registration__c>();
    Map<Boolean, Registration__c> regMap3 = new Map<Boolean, Registration__c>();       
    for (Registration__c regReq : System.Trigger.new) {
                // store registration pertinent values
                regmap.put(regReq.Account__c, regReq);
                regmap1.put(regReq.Product__c,regReq);
                regmap2.put(regReq.Duplicate_Registration__c,regReq);
                //regmap3.put(regReg.Manufacturer_Name__c,regReq      
    //Loop through and make sure no duplicates exist    //fields are Account, Product         
    for (Registration__c reg : [SELECT Account__c,Product__c,Manufacturer__c, Registration_Status__c FROM Registration__c]) {
   If (regReq.Duplicate_Registration__c == False && regReq.Account__c == regReq.Account__c && reg.Product__c == regReq.Product__c )      {
       regReq.addError('Registration for this Product already exists. If you want to enter it anyway, check the "Account has multiple locations" checkbox'  + ' and fill out the Location field');      
      }// end regReq.Duplicate_Registration__c   
}  //end for (Registration__c reg :
} // for (Registration__c regReq
}// end trigger

Registration Request object has 2 triggers Before insert and After insert
The before insert is:  This checks to see if a duplicate record exists and if so throw a message.
trigger stopDuplicateRegRequest on Registration_Requests__c (before insert, before update) {
    Map<String, Registration_Requests__c> regMap = new Map<String, Registration_Requests__c>();
    Map<String, Registration_Requests__c> regMap1 = new Map<String, Registration_Requests__c>();   
    Map<Boolean, Registration_Requests__c> regMap2 = new Map<Boolean, Registration_Requests__c>();
       
    for (Registration_Requests__c regReq : System.Trigger.new) {
                // store registration Request pertinent values
                regmap.put(regReq.Account__c, regReq);
                regmap1.put(regReq.Product__c,regReq);          
                regmap2.put(regReq.Duplicate_Registration__c,regReq); 
      
    //Loop through and make sure no duplicates exist
    //fields are Account, Product 
   
    for (Registration__c reg : [SELECT Account__c,Product__c, Registration_Status__c, Duplicate_Registration__c FROM Registration__c])
{
   If (regReq.Duplicate_Registration__c == False && reg.Account__c == regReq.Account__c && reg.Product__c == regReq.Product__c )
      {
      regReq.addError('Registration for this Product already exists. If you want to enter it anyway, check the "Account has multiple locations" checkbox'
                       + ' and fill out the Location field');
      regReq.StopInsert__c = True;                
       }// end if
      
} //end for (Registration__c reg
}//for (Registration_Requests__c

       }//end trigger

The after trigger is:  It is just a simple record creation.

trigger Reg_Request_to_Reg on Registration_Requests__c (after insert) {
    List<Registration__c> newRegistration = new List <Registration__c>();
   
           for (Registration_Requests__c reg : trigger.new) {
           
            Registration__c newReg = new Registration__c();
            newReg.Account__c = reg.Account__c;
            newReg.Opportunity__c = reg.Opportunity_Name__c;
            newReg.Product__c = reg.Product__c;
            newReg.Manufacturer_Name__c = reg.Manufacturer_Name__c;
            newReg.Inside_Sales_Rep__c = reg.Inside_Sales_Rep__c;
            newReg.Location__c = reg.Location__c;
            newReg.Duplicate_Registration__c = reg.Duplicate_Registration__c;
            newReg.Registration_Request_URL__c = 'https://na12.salesforce.com/' + reg.ID;
            newRegistration.add(newReg);
           
        }//end for
       
        insert newRegistration;
       
        }//end trigger
Best Answer chosen by Eric Blaxton
sfdcfoxsfdcfox
You're not adding the error to the Trigger.new record, and so no error is detected. Your trigger should look like this:

<pre>
trigger stopDuplicateRegRequest on Registration_Requests__c (before insert, before update) {
Map<Id, Map<Id, Registration_Requests__c>> requests = new Map<Id, Map<Id, Registration_Requests__c>>();
Set<Id> recordIds = new Set<Id>();

for(Registration_Requests__c record: Trigger.new) {
  requests.put(record.Product__c, new Map<Id, Registration_Requests__c>());
  recordIds.add(record.Product__c);
}
for(Registration_Requests__c record: Trigger.new) {
  if(requests.get(record.Product__c).containsKey(record.Account__c)) {
   record.addError('Duplicate registration in this request');
  } else {
   requests.get(record.Product__c).put(record.Account__c, record);
  }
  recordIds.add(record.Account__c);
}
// Detect duplicates in the system
for(Registration_Requests__c record: [SELECT Id, Account__c, Product__c FROM Registration_Requests__c WHERE Account__c IN :recordIds AND Product__c IN :recordIds]) {
  if( requests.get(record.Product__c) != null &&
   requests.get(record.Product__c).get(record.Account__c) != null &&
   requests.get(record.Product__c).get(record.Account__c).Id != record.Id &&
   !requests.get(record.Product__c).get(record.Account__c).Duplicate_Registration__c) {
   requests.get(record.Product__c).get(record.Account__c).addError('Duplicate registration request found.');
  }
}
}
</pre>

All Answers

hitesh90hitesh90
Hi,

Yes, add error message in before insert trigger to stop to execute after insert trigger.
trigger.addError
this will stop further executions.

Thank You,
Hitesh Patel
SFDC Certified Developer & Administrator & Advanced Administrator & Sales cloud consultant
My Blog:- http://mrjavascript.blogspot.in/
Eric BlaxtonEric Blaxton
Hi and thanks for your time, I tried what you suggested, but the error message I got was the Error: Compile Error: Variable does not exist: trigger at line 23 column 7 I also tried with the actual name of the triggerName.addError and got the same error: Variable does not exist: stopDuplicateRegRequest at line 23 column 7 trigger stopDuplicateRegRequest on Registration_Requests__c (before insert, before update) { Map regMap = new Map(); Map regMap1 = new Map(); Map regMap2 = new Map(); for (Registration_Requests__c regReq : System.Trigger.new) { // store registration Request pertinent values regmap.put(regReq.Account__c, regReq); regmap1.put(regReq.Product__c,regReq); regmap2.put(regReq.Duplicate_Registration__c,regReq); //Loop through and make sure no duplicates exist //fields are Account, Product and Status != 'Closed' for (Registration__c reg : [SELECT Account__c,Product__c, Registration_Status__c, Duplicate_Registration__c FROM Registration__c]) { If (regReq.Duplicate_Registration__c == False && reg.Registration_Status__c != 'Closed' && reg.Account__c == regReq.Account__c && reg.Product__c == regReq.Product__c ) { // regReq.addError('Registration for this Product already exists. If you want to enter it anyway, check the "Account has multiple locations" checkbox' // + ' and fill out the Location field'); trigger.addError('Registration for this Product already exists. If you want to enter it anyway, check the "Account has multiple locations" checkbox' + ' and fill out the Location field'); }// end if } //end for (Registration__c reg }//for (Registration_Requests__c }//end trigger
sfdcfoxsfdcfox
You're not adding the error to the Trigger.new record, and so no error is detected. Your trigger should look like this:

<pre>
trigger stopDuplicateRegRequest on Registration_Requests__c (before insert, before update) {
Map<Id, Map<Id, Registration_Requests__c>> requests = new Map<Id, Map<Id, Registration_Requests__c>>();
Set<Id> recordIds = new Set<Id>();

for(Registration_Requests__c record: Trigger.new) {
  requests.put(record.Product__c, new Map<Id, Registration_Requests__c>());
  recordIds.add(record.Product__c);
}
for(Registration_Requests__c record: Trigger.new) {
  if(requests.get(record.Product__c).containsKey(record.Account__c)) {
   record.addError('Duplicate registration in this request');
  } else {
   requests.get(record.Product__c).put(record.Account__c, record);
  }
  recordIds.add(record.Account__c);
}
// Detect duplicates in the system
for(Registration_Requests__c record: [SELECT Id, Account__c, Product__c FROM Registration_Requests__c WHERE Account__c IN :recordIds AND Product__c IN :recordIds]) {
  if( requests.get(record.Product__c) != null &&
   requests.get(record.Product__c).get(record.Account__c) != null &&
   requests.get(record.Product__c).get(record.Account__c).Id != record.Id &&
   !requests.get(record.Product__c).get(record.Account__c).Duplicate_Registration__c) {
   requests.get(record.Product__c).get(record.Account__c).addError('Duplicate registration request found.');
  }
}
}
</pre>
This was selected as the best answer
Eric BlaxtonEric Blaxton
Hi and thanks again for your time. I tried what you suggested and am getting this error message when a duplicate is found. Even though the error is thrown on Before Insert, the After Insert continues to run and catches the error as seen below. Error: Invalid Data. Review all error messages below to correct your data. Apex trigger Reg_Request_to_Reg caused an unexpected exception, contact your administrator: Reg_Request_to_Reg: execution of AfterInsert caused by: System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Registration for this Product already exists. If you want to enter it anyway, check the "Account has multiple locations" checkbox and fill out the Location field: []: Trigger.Reg_Request_to_Reg: line 19, column 1 This behavior is acceptable, but I want the error message to be cleaner, "Registration for this Product already exists. If you want to enter it anyway, check the "Account has multiple locations" checkbox and fill out the Location field"
Eric BlaxtonEric Blaxton
Thanks sfdcfox, I was achieving the same results with the Trigger I wrote. The After Insert trigger is not performing the insert because of the error message thrown in the Before Insert trigger. Is there a way to actually stop the processing, if the error is caught in the Before trigger. Thanks,