10

[Salesforce Update] The critical update named “PageReference getContent() and getContentAsPDF() Methods Treated as Callouts” was scheduled for auto-activation in Winter ’16. To allow for planning and implementing the solution, the auto-activation date has been postponed until Spring ’16.

Read more @ https://partners.salesforce.com/partnerAlert?id=a033000000GAPdDAAX

We use the GetContentAsPDF to generate PDF documents and attach them to the relevant record. This function is called in the following 2 scenarios:

  1. When a condition on a record is satisfied as it is updated. In this scenario, we call a future method and in the future method, a Apex callout is made to a REST service which generates the document and attaches to the record.
  2. A batch class runs once every day to find out the records which satisfy our criterias and if they do, we make a Apex Callout to the same Rest Service which generates the document and attaches to the record.

This all worked fine. But after the Spring 15 release, getContentAsPDF will be counted as a callout. We enabled the critical update in Sandbox (this update will be auto applied to production on 11th September). Once updated, the logic no longer works. We get an error called 'Callout Loop not allowed'. Makes sense because we are now doing another callout from the callout function.

Does anyone have an idea on how to solve this? We are trying different approaches here but none have worked.

Update [26Aug'15]: I got hold of a prerelease org with Winter'16 features enabled and wrote a simple code to

  • Fire a trigger on Account Update
  • Call a future method
  • Do getContent in future method.
  • Attach the document as attachment under Account

It worked fine and the attachment also had proper details. I tried the same code in our sandbox which had the critical update applied and the attachment generated was blank.

So basically, till Winter'16 changes are applied (sometime in October), there is no way to use getContent() or getContentAsPDF() batch apex or future class. Are there any alternatives? I have tried Post methods, future to post to future. None have worked.

  • Can you call the service logic directly from code? Excuse me if there's a limitation that prohibits that. – zokito Aug 25 '15 at 10:36
  • We did that; it doesn't throws any error but the document generated is blank. – RajeshShah Aug 25 '15 at 10:49
  • Although the REST class in one case is launched from an \@future (and \@future methods can't call other \@future methods), the REST class is running in a separate transaction because it is a callout and so can make an \@future call to generate the PDF and so avoid the error. – Keith C Aug 25 '15 at 12:29
  • @KeithC So you are suggesting the following flow: - Trigger calls future method - Future method calls rest service - In the rest service, do GetContentAsPDF. I am doing the same flow currently but it fails. – RajeshShah Aug 25 '15 at 13:39
  • 1
    In the Winter '16 release, getContent() and getContentAsPDF() can be invoked from within Asynchronous Apex such as Batch Apex, Schedulable and Queueable classes, and @future methods. So now you will be able to call PageReference getContent() and getContentAsPDF() methods from within Asynchronous Apex. You should have access to a pre-release org to start using this functionality. Here is a partner community post where this is discussed: partners.salesforce.com/0D530000020ek7L – Chirag Mehta Aug 26 '15 at 1:11
2

With Winter`16 release it would be resolved. Partners says:

In the Winter '16 release, getContent() and getContentAsPDF() can be invoked from within Asynchronous Apex such as Batch Apex, Schedulable and Queueable classes, and @future methods. This provides an alternate solution for any partners impacted by the upcoming Critical Update and allows you to design much more flexible and scalable services that, for example, render Visualforce pages as PDF files.

  • When would the Winter'16 release be live on Production orgs? The Critical Update will be auto applied on 11th Sep, so winter 16 is applied after that, we would need an interim solution for this. – RajeshShah Aug 26 '15 at 9:09
  • As an interim solution can't you break the logic using a schedulable batch in your rest resource. It seem like you have written a apex rest service. That batch will generate the pdf and attach to record. rest resource will schedule it – Ashwani Aug 26 '15 at 9:13
  • When we do GetContentAsPDF from a batch class, it generates a blank document. No error but just a blank document. That was reason we had to switch to rest service. – RajeshShah Aug 26 '15 at 9:18
  • @RajeshShah Did you tried with current release that you are still getting bank document. With previous release I am sure that blank document get generated. – Ashwani Aug 26 '15 at 9:28
  • 1
    Yes, we are getting a blank document. – RajeshShah Aug 26 '15 at 11:43
0

To clarify my comment, I am suggesting that in the REST service you do this:

  @HttpPost  
  global static ... post(...) {
      // Do other processing
      generatePdf(...);
  }

  @future(callout=true)
  private static void generatePdf(Id id) {
      // Generate
      // Attach
  }

to avoid the loop.

  • Ok. I will try this out. Currently my code to generate the PDF is inside the post function. May I know why it would not work directly in the post method and would work in the Future method? Also, if this works, then shouldn't the following flowalso work? 1. Trigger calls future method. 2. Future method does generatePDF. i.e. I am calling the generatePDF directly from trigger. – RajeshShah Aug 25 '15 at 14:04
  • If you do any DML (e.g. update/insert) in the POST method then you won't be able to do the implicit callout without the future call. But I think the reason the future will help is hinted at in this Callout loop not allowed error; the future avoids any blocking of the POST call by allowing the work to be done later on. – Keith C Aug 25 '15 at 14:10
  • But if this works, shouldn't the flow that I mentioned (calling future directly from trigger to generatePDF) work? Is there a difference between calling from trigger and calling from Post method? – RajeshShah Aug 25 '15 at 14:19
  • @RajeshShah Yes I think it will as long as there is no DML. (Your question is not about that though.) – Keith C Aug 25 '15 at 14:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.