+ Start a Discussion
SYM12SYM12 

System.Exception: Too many callouts: 11

Hi All,

 

i have written a trigger on campaign and which calls a future method when the campign is close. but i am getting the below error

 

Failed to invoke future method 'public static void updateLead(LIST:String)'

caused by: System.Exception: Too many callouts: 11

Class.TwilioRestClient.

request: line 70, column 32
Class.CommonUpdateUrl.UpdateOutOfServiceUrl: line 62, column 14
Class.CampClosed.updateLead: line 91, column 8
External entry point
below is the my class
public with sharing class CampClosed {

@future(callout=true)
public static void updateLead(List<String> CampaignList){

List<Lead> LeadToUnassign = new List<Lead>();
List<String> VN = new List<String>();
list<String> ListIds = new list<String>();
list<String> UpdateURL = new list<String>();
list<Lead_Virtual__c> vnn = new list<Lead_Virtual__c>();
if(CampaignList.size()>0)

    {   
        list<lead> Checklist = new list<Lead>();
        Checklist = [Select Id from Lead where FCCampaign__c In :CampaignList and Status ='Trial'limit 10];
        if(Checklist.size()>0){
          list<Twilio_URL__c> t1 = [select Id,Name,URL_Value__c from Twilio_URL__c  where Name = 'Out Of Service' limit 1];
        System.debug('Before Lead');
for(list<Lead> l1: [Select Id,Status,Phone,Virtual_Number__c,FCCampaign__c,Actual_End_Date__c,IsProvisioned__c,
                    (Select Id, Status__c From Lead_Virtuals__r) from Lead where FCCampaign__c In :CampaignList and Status ='Trial']) {
       for(Lead l2 :l1){
       VN.add(l2.Virtual_Number__c);
       l2.Status = 'Cancel';
       l2.Provisioning_Status__c ='Pending';
      l2.Virtual_Number__c= '';
      l2.Actual_End_Date__c= System.today();
      l2.IsProvisioned__c = false;                          
         LeadToUnassign.add(l2);
        ListIds.add(l2.Id);
       }
    //   for(Lead_Virtual__c temp :l1.Lead_Virtuals__r){
      //         temp.Status__c = 'Inactive';
        //     vnn.add(temp);
      // }
         if (LeadToUnassign.size() == 200) {
        //  for(Virtual_Number__c v1 :)
            try {
                list<Lead_Virtual__c> vr1 = [Select Id,Status__c from Lead_Virtual__c where Lead__c IN :ListIds
                                                                        and Status__c = 'Active'];
                List<Virtual_Number__c> V1 = new List<Virtual_Number__c>();
                V1 =[Select Id,Virtual_Number__c,SID__c,Twilio_URL__c from Virtual_Number__c where Virtual_Number__c IN :VN];
                for(Virtual_Number__c v2 :V1){
                    v2.Virtual_Number_Staus__c = 'Hold';
                    v2.Twilio_URL__c =t1[0].Id;
                    UpdateURL.add(v2.SID__c);
                }
                
                for(Lead_Virtual__c vr2 :vr1){
                    vr2.Status__c = 'Inactive';
                }
                System.debug('Before Update');
                if(UpdateURL.size()>=600){
                    CommonUpdateUrl.UpdateOutOfServiceUrl(UpdateURL);
                    UpdateURL.clear();
                }
                update LeadToUnassign;
                update V1;
                update vr1;
                System.debug('After Update');
                LeadToUnassign.clear();
                VN.clear();
                ListIds.clear();
            //  PassUpadateURLParametes.PassParameter(UpdateURL);
            

            } catch(Exception ex) {
                System.debug(' Exception Occured' + ex);     
            //  sentEmail(i);  
                LeadToUnassign.clear();
                VN.clear();
                ListIds.clear();    
            }                                           
       }  
                                 }                                              
    if (! LeadToUnassign.isEmpty()) {
        try {
            System.debug('2nd  if statement');
            list<Lead_Virtual__c> vr1 = [Select Id,Status__c from Lead_Virtual__c where Lead__c IN :ListIds
                                                                    and Status__c = 'Active'];
            List<Virtual_Number__c> V1 = new List<Virtual_Number__c>();
                V1 =[Select Id,Virtual_Number__c,SID__c,Twilio_URL__c from Virtual_Number__c where Virtual_Number__c IN :VN];
                for(Virtual_Number__c v2 :V1){
                    v2.Virtual_Number_Staus__c = 'Hold';
                    v2.Twilio_URL__c =t1[0].Id;
                    UpdateURL.add(v2.SID__c);
                }
                for(Lead_Virtual__c vr2 :vr1){
                    vr2.Status__c = 'Inactive';
                }
            if(!UpdateURL.isEmpty()){
                CommonUpdateUrl.UpdateOutOfServiceUrl(UpdateURL);
            }
                            update LeadToUnassign;
                update V1;
                update vr1;
            //  update VN;
            LeadToUnassign.clear();
                VN.clear();
        } catch(Exception ex) {
            System.debug(' Exception Occured' + ex);
        //  sentEmail(i);
        
        }
    }      
                                       }       
      else{
        System.debug('No Lead is Active');
           }                                                                            
                                       }                                        
    }
}
Please suggest how i can get over from this problem.
Thanks,

SYM12SYM12

Any Suggestion....

bob_buzzardbob_buzzard

You are receiving this error because you have exceeded the governor limit for the total number of callouts in a transaction, which is 10.

 

Its a little difficult to read the code as the indentation gets a bit lost on these boards if you don't paste as code.  Presumably you are looping through a collection and executing a callout?  The usual solution here is to bulkify the trigger so that you reduce the number of calls and don't break the governor limit.  However, as you are using a callout, it really depends on whether you can batch up into a single callout.

 

 

SYM12SYM12

Hey Bob ,thanks for your reply

 

No i cant send multiple record in single collout as API dont have any list or map acceptance.

 

Is there any way if i can scedule 100 callouts and let them run for 100 mins till they finish? are there any governer limits?

 

Thanks in advance

Mayank_JoshiMayank_Joshi
That's true , Trigger can't process more than 10 records usibg future methods . For bulk , it will hit too many future callout error .

For this, you may need to implement batch process that can process bulk recirds from trigger .

I had a similar situation for sending more than 10 records. Finally , I resolved this issue and now batch is successfully processing 'n' number of records in Outbound Callouts .

Here Few things need to be focused :

Outbound method should be non future method,for the case of batch apex .

1 : global class Send_closed_CA implements Database.Batchable<Sobject>, Database.AllowsCallouts{ }

Always required - Database.AllowsCallouts while implementing batch for outbound callouts .

2: Next , most Important . As per documentation Batch Apex can process 200 Records per batch . But , while making callouts Batch Apex can only process 1 record per batch(as per documentation) .To overcome this ,we have to make scope of 1 within a batch .

That means , if we are going to send(outbound ) for any no. of records per batch then scope defined for this should be only - One (1) .

Note - we have to manually set Scope for batch, if there is need to set batch other than 200 . But , scope should only be in range of 1- 199 .

Eg . for executing batch apex code for Outbound callouts with scope defined as One .
Batch_closed_ca batchapex = new Batch_closed_ca();

// Defining scope for the batch ...
id batchprocessid = Database.executebatch(batchapex,1);
system.debug('Process_ID: ' + batchprocessid);