[SalesForce] Heap size limit error when making a callout to external endpoint

We are making a callout to external endpoint from Salesforce to get the attachments. when attachment size is more than 6 MB its throwing me Heap size limit error and we are running this callout from future method where we are having this limit as 12 MB.

Please advise ….

Code here …

@future(callout=true)
    public static void SendAttachmentsToCase(Map<string,string> Initialres,ID CaseID,ID UserID,string UserName,string Password,string ticketNumber,string jobtime)
    {

                // Performs another callout to get appropriate attachment 
               List<attachment> FinalAttachmentList = new List<attachment>();
               for(string sg : Initialres.Keyset()) // Map of attachment Names and endpoint
               {
                Http h2 = new Http();
                HttpRequest req2 = new HttpRequest();
                Blob headerValue = Blob.valueOf(UserName+':'+Password);
                String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
                req2.setHeader('Authorization', authorizationHeader);
                req2.setHeader('Content-Type','application/json');
                req2.setEndpoint(Initialres.get(sg));
                req2.setMethod('GET');
                req2.setTimeout(60000);
                try
                {
                system.debug('heap size before req'+' '+ Limits.getHeapSize());
                HttpResponse res2 = h2.send(req2); // Hitting the error at this line. It shows me the heap size before the HTTP req
                system.debug('resposne'+ ' '+res2.getBody());
                                system.debug('heap size after req'+' '+ Limits.getHeapSize());

                blob image = res2.getBodyAsBlob(); 
                Attachment a = new Attachment (ParentId = CaseID,
                                           Body = image,
                                           OwnerId = UserID,
                                           CreatedById = UserID,
                                           Name = sg);
               FinalAttachmentList.add(a);
                }catch (Exception e)
                {
                    system.debug('exception message at 2nd callout level'+ ' '+ e.getMessage());
                 }
              }

              insert FinalAttachmentList;
    }

Best Answer

As I can see from your code, you are storing all attachment in a list and then inserting it. This behaviour is making you store and consume the heap limit bit more than your actual attachment size.

I know its ugly, but for this I recommend you doing a DML inside a for loop.

The memory scope of for-loop is per iteration. After completion of iteration the memeroy is garbage collected. Thus freeing your loop consumed memory.

If you un-bulkify your code it will help you save that attachment.

@future(callout=true)
    public static void SendAttachmentsToCase(Map<string,string> Initialres,ID CaseID,ID UserID,string UserName,string Password,string ticketNumber,string jobtime)
    {


               for(string sg : Initialres.Keyset()) // Map of attachment Names and endpoint
               {
                Http h2 = new Http();
                HttpRequest req2 = new HttpRequest();
                Blob headerValue = Blob.valueOf(UserName+':'+Password);
                String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
                req2.setHeader('Authorization', authorizationHeader);
                req2.setHeader('Content-Type','application/json');
                req2.setEndpoint(Initialres.get(sg));
                req2.setMethod('GET');
                req2.setTimeout(60000);
                try
                {
                system.debug('heap size before req'+' '+ Limits.getHeapSize());
                HttpResponse res2 = h2.send(req2); // Hitting the error at this line. It shows me the heap size before the HTTP req
                system.debug('resposne'+ ' '+res2.getBody());
                                system.debug('heap size after req'+' '+ Limits.getHeapSize());

                blob image = res2.getBodyAsBlob(); 
                Attachment a = new Attachment (ParentId = CaseID,
                                           Body = image,
                                           OwnerId = UserID,
                                           CreatedById = UserID,
                                           Name = sg);
               insert a;
                }catch (Exception e)
                {
                    system.debug('exception message at 2nd callout level'+ ' '+ e.getMessage());
                 }
              }


    }
Related Topic