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
sflearnsflearn 

bulkify catch block

The before update trigger below passes trigger records  into the parentObjectMap. I am running various test methods and when i run my bulk tests to the parent object it says too many future calls.  I think my catch block is not bulified so every time there is more than 10 records that are bad , the future class is called to many time. how could i bulkify that? Eveything else works fine. basically, if the child items are incomplete i throw an error to the parent object

 

 

try{
    for(childObject: childObjectList){
      if(childObject.custom_field__c == null)

         parentObjectMap.get(childObject.ParentObjectId).addError('Incomplete child items');

      }
}

   if(test.isRunningTest())
   {
       throw new TestException('Exception');
    }
}

 

catch(Exception ex) {
FutureErrorlog.createExRec(ex.getMessage());
}
}

 

 

global class FutureErrorlog{
@future
public static void createExRec(string exceptionMessage){
Error_Log__c exceptionRec = new Error_Log__c(
Error_Message__c = exceptionMessage);
insert exceptionRec;
}
}

 

 

ryanjuptonryanjupton

There's no way to 'bulkify' a catch since it's linked to the try that executes for each record. Curious, why are you using a future method in your class? It's not really clear what exactly you're trying to do with the code you've posted. I have an idea of something that might work but don't want to speculate.  If you can clarify what you're doing, that would be great.

bob_buzzardbob_buzzard

How is this code executed?  I.e. is there an outer loop that is iterating a collection or similar?

 

If so, you could capture the error messages into a list of strings and pass the collection to your future method.

sflearnsflearn

Hi - right before my try block, I have this code below.  My parentObjectMap is a map passed in from  the trigger which is the Parent Object Ids and the Parent Object is the trigger object for a before update.  My intent was actually to test bulk behaivor and ensure no exceptions are thrown but something was wrong with my test data so i inadverdently invoked my catch block which caused the too many future calls - good thing I found this but not sure how to fix it.

 

    public static void childListValidator(Map<Id, ParentObject> parentObjectMap){

        List<ChildObject> childObjectlist=  

                                                     [SELECT Id, ParentObjectId 

                                                      From ChildObject

                                                      WHERE ParentObjectId IN parentObjectMap.keySet()];

     try{

       //logic to locate bad child items and throw an error to parent record

    }

 

     catch(exception ex)

    { 

    send unexpected exceptions to future class

   }

 

 

bulk test

    static testMethod void  testBulkPositive()

    {

          // calls my test factory

            List<ParentObject> pList= TestFactory.getParentObjects('Test, 200);

            integer beforeOppCount =[SELECT COUNT() 

                                                           FROM ParentObject ]; 

            Test.startTest();           

            List<ChildObject> childObjectList = TestFactory.getChildObjects(parentObjectId.Id,200, 100.00, true);

            List<ParentObject> updatePlist  = new List<ParentObject>();

            integer afterOppCount =[SELECT COUNT() 

                                                       FROM ChildObject 

                                                    WHERE ParentId =: ParentObject.Id];           

            for(ParentObject p: pList)

           {

                p.custom_field__c = 'test';

                 updatePlist.add(p);

           }

   //my assert here to check all parentobjects are updated

      Test.stopTest();

sflearnsflearn

Hi thank you. The goal of my trigger is to throw an error on the opportunity record if opplineitem doesn't have certain fields filled in.  I am using a future method since we don't essentially want to display an unpexpected exception to the user but rather throw it into an error log that the dev team can analyze and figure async would be a better approach for higher goveronor limits. My trigger passes all tests but the bulk since my bulk is calling the future class too many times..any help would be great

bob_buzzardbob_buzzard

I don't understand how your logic works - according to the code you have posted, if you encounter an exception you will make a future callout and then exit the method - that won't breach any limits.

sflearnsflearn

actually I ran the tests again and it worked. So according to my logic if I load 200 bad opportunity records(with exceptions) would the future call be able to handle the bulk processing...i have a feeling it may crash not sure though

bob_buzzardbob_buzzard

That depends on whether the code posted earlier was accurate.  The way that worked, the records were iterated and if any error occured, the future method was called and the method exited.  

 

The only way I can see that you would break limits is if you had the future call inside the loop that iterates the records.

sflearnsflearn

ok here is my code pasted from the dev. My goal is to be able that ona  bulk load, the async handler would be able to retain the exception for each record without causing a future limit exception..

 

public class OppUtil{

public static void oppLineItemVal(Map<Id, Opportunity> myMap){
List<OpportunityLineItem> oliList=
[SELECT Id, OpportunityId, LineItemCompleted
FROM OpportunityLineItem
WHERE
AND OpportunityID IN: oMap.keySet()];

List<Opportunity> oppList = new List<Opportunity>();
try{
for(OpportunityLineItem lineItem: oliList){
if(oli.LineItemCompleted == null){
oMap.get(lineItem.OpportunityId).addError('Not Complete!!');
oppList.add(oMap.get(lineItem.OpportunityId));Quote
}
}


}
catch(Exception ex) {
system.debug('x');
}
}

}

 

 

 

global class FutureErrorlog{
@future
public static void createExRec(string exceptionMessage){
Error_Log__c error = new Error_Log__c(
Message__c = exceptionMessage);
insert error;
}
}

bob_buzzardbob_buzzard

That will be fine from a limits point of view, as you can only ever make one call to FutureErrorLog.create, due to the try/catch being outside of the loop.  However, this may not be what you want, as the first exception will cause the loop to exit and won't process the rest of the records.

tdevmantdevman

Thank you bob- should i simply place the try statement right after the for statement? I think this will ensure each record is processed independently since my bulk test method uses database.update to process partial processing in a before trigger context.

 

2nd question is since i don't want it to fire on my positive test cases..should i create a static boolean and place it in the excpetion assertion testmethods so it if( isRunningTest && exceptionFlag = true) then // throw an error