+ Start a Discussion
TheCustomCloudTheCustomCloud 

A Trigger Error

I've been staring at this code too long and I think something obvious isn't jumping out at me.  I have a recursive trigger causing me to hit the maximum trigger depth but I can't think of how to fix it.  If anyone can help I am posting the trigger in it's entirety and the error.

 

THANKS!

 

The scenario is a user updates a custom revenue object.  This fires a trigger to update the record with the "Prior Year Revenue"  and also update the next year's "Prior Year Revenue".

 

trigger RollUpPriorYear_AIAU on Revenue__c (before insert, before update, after update, after insert){
    Set<String> pastKeys = new Set<String>();
    Set<String> futureKeys = new Set<String>();
    
    Map<String, Revenue__c> currentRevs = new Map<String, Revenue__c>();
    Map<String, Revenue__c> futureRevs = new Map<String, Revenue__c>();
     
    // key: Internal id corrected to last year, total prior year amount 
    Map<String, Integer> pastTotalPriors = new Map<String, Integer>();
    List<Revenue__c> priorRevs = new List<Revenue__c>();
    
    // revenue to be updated
    List<Revenue__c> futurePlaceHolders = new List<Revenue__c>(); 
    List<Revenue__c> futureRevsToBeUpdated = new List<Revenue__c>();
    
    for(Revenue__c r: trigger.new){    
        // gather the internal ids
        
        // current 
        currentRevs.put(makeKey(r, 0), r);
        
        // past
        pastKeys.add(makeKey(r, -1));
        
        // future
        futureKeys.add(makeKey(r, 1));  
    }
    
    // retrieve all the past total forecasted
    for(Revenue__c re: [SELECT Account__c,Team__c,User__c,Total_Forecast__c,Quarter__c,Fiscal_Year__c,Platform__c FROM Revenue__c WHERE InternalId__c IN : pastKeys]){
        String reKey = makeKey(re, 0);
        if(pastTotalPriors.containsKey(reKey)){
            Integer aTotal = pastTotalPriors.get(reKey);
            aTotal += Integer.ValueOf(re.Total_Forecast__c);
            pastTotalPriors.put(reKey,aTotal); 
        }
        else{
            pastTotalPriors.put(reKey,Integer.ValueOf(re.Total_Forecast__c));
        }
        
        priorRevs.add(re);
    }
    
    // create placeholders if no current rev exists to hold prior rev
    for(Revenue__c pr : trigger.new){
        if(!futureRevs.containsKey(makeKey(pr,0))){
            Revenue__c ph = new Revenue__c();
            ph.Account__c = pr.Account__c;
            ph.Team__c = pr.Team__c;
            ph.Platform__c = pr.Platform__c;
            ph.Fiscal_Year__c = String.ValueOf(Integer.ValueOf(pr.Fiscal_Year__c.substring(0, 4)) + 1); 
            ph.Fiscal_Year__c += '-';
            ph.Fiscal_Year__c += String.ValueOf(Integer.ValueOf(pr.Fiscal_Year__c.substring(5, 7)) + 1);
            ph.Quarter__c = pr.Quarter__c;
            ph.User__c = pr.User__c;
            ph.Date__c = pr.Date__c;
            futurePlaceHolders.add(ph);
        }
    }
    
    if(trigger.isBefore){
        // this deals with updating past revenue records
        for(Revenue__c r: trigger.new){
            system.debug('*** updating the following pastTotalPriors: ' + pastTotalPriors);  
            r.Final_Prior_Year__c = pastTotalPriors.get(makeKey(r,-1));
        }
    }  
    
    if(trigger.isAfter){
        // this deals with updating future revenue records - so they also fire this trigger
        for(Revenue__c rev: [SELECT id FROM Revenue__c WHERE InternalId__c IN : futureKeys]){
            futureRevsToBeUpdated.add(rev);
            futureRevs.put(makeKey(rev,0),rev);
        }
        update futureRevsToBeUpdated;
        
        // this creates placeholders for prior year revenue values sitting on the current year revenue records
        // THIS IS GIVING ME THE ERRORS
        insert futurePlaceHolders; 
    }
    
// utility method    
    private String makeKey(Revenue__c rev, Integer yrAdj){
        //Account__c + Team__c + TEXT( Platform__c ) + Fiscal_Year__c + TEXT( Quarter__c ) + User__c
        String theKey = String.ValueOf(rev.Account__c).substring(0, 15);
        theKey += String.ValueOf(rev.Team__c).substring(0, 15);
        theKey += rev.Platform__c;
        theKey += Integer.ValueOf(rev.Fiscal_Year__c.substring(0, 4)) + yrAdj;
        theKey += '-';
        theKey += Integer.ValueOf(rev.Fiscal_Year__c.substring(5, 7)) + yrAdj;
        theKey += rev.Quarter__c;
        theKey += String.ValueOf(rev.User__c).substring(0, 15);
        System.debug(' *** theKey: ' + theKey);
        return theKey;
    }
}

 

Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger RollUpPriorYear_AIAU caused an unexpected exception, contact your administrator: RollUpPriorYear_AIAU: execution of AfterInsert caused by: System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, RollUpPriorYear_AIAU: maximum trigger depth exceeded Revenue trigger event AfterInsert for [a06c0000000Y7Ds] Revenue trigger event AfterInsert for [a06c0000000Y7Dt] Revenue trigger event AfterInsert for [a06c0000000Y7Du] Revenue trigger event AfterInsert for [a06c0000000Y7Dv] Revenue trigger event AfterInsert for [a06c0000000Y7Dw] Revenue trigger event AfterInsert for [a06c0000000Y7Dx] Revenue trigger event AfterInsert for [a06c0000000Y7Dy] Revenue trigger event AfterInsert for [a06c0000000Y7Dz] Revenue trigger event AfterInsert for [a06c0000000Y7E0] Revenue trigger event AfterInsert for [a06c0000000Y7E1] Revenue trigger event AfterInsert for [a06c0000000Y7E2] Revenue trigger event AfterInsert for [a06c0000000Y7E3] Revenue trigger event AfterInsert for [a06c0000000Y7E4] Revenue trigger event AfterInsert for [a06c0000000Y7E5] Revenue trigger event AfterInsert for [a06c0000000Y7E6] Revenue trigger event AfterInsert for [a06c0000000Y7E7]: []: Trigger.RollUpPriorYear_AIAU: line 79, column 1

MrTheTylerMrTheTyler

Hello,

 

  Any time recursion is used in programming some sort of exit condition must be specificied or your will have an infinite loop that will always crash.  The platform allows a max recursive depth of 16 - but from a quick glance at your code, your would theoretically recurse infintely. You will need to write some code to decide if "insert futurePlaceHolders;" should be called.

 

Kind Regards,

 

Tyler Hudson
Contact Us - We Can Help!

Salesforce Superheroes
------------------------------
help@salesforcesuperheroes.com
www.salesforcesuperheroes.com
1-888-407-9578 x123