0

I have a platform event trigger that calls a method in a class that is annotated with @future. This future method makes an external REST api call to get some data and updates values on the Opportunity object. This works well.

On the Opportunity object I have an "after update" trigger that when the the field value change as result of the above, it in turn makes another external REST api call using a method that is also annotated with @future shown below:


public static void AfterUpdate(Map<Id, SObject> newItems, Map<Id, SObject> oldItems) {

    Opportunity oldOpp = (Opportunity) oldItems.get(oppId);
    Opportunity newOpp = (Opportunity) newItems.get(oppId);

    JSONGenerator gen=JSON.createGenerator(true);

     gen.writeStartObject();
       gen.writeFieldName('job_title');
      //...more json generated... 
    gen.writeEndObject();

    //calls the below future method
    makeCallout(gen.getAsString(),newOpp.Id);
}

 @future (callout=true)
 public static void makeCallout(String jsonBody,Id oppId) {
        String endpoint = 'callout:' + getEnvironmentSettings().get('apiURL') + '/jobapplications?apikey=' + getEnvironmentSettings().get('apiKeyValue');

        Http h = new Http();
        HttpRequest req = new HttpRequest();
        req.setEndpoint(endpoint);
        req.setBody(jsonBody);
        req.setMethod('POST');
        req.setHeader('Content-Type', 'application/json');
        HttpResponse res = h.send(req);

       Map<String, Object> jsonResults = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
}

The above scenario is failing with the error "Future Method cannot be called from another Future Method" even though I am not directly calling a future method from another future method, I am guessing the error is happening because of the way future methods work.

How can I modify or refactor the future method above to avoid this error?

  • 1
    In your use case you are using @future to avoid the limitation around triggers (cannot execute callouts with good reason). Your triggers are chaining and the future callouts are being nested one inside the other. I would suggest looking into CDC for the Opportunity object and having an Asynchronous trigger on opp to perform the second callout. You would still need future annotation but you wouldn't see this issue: developer.salesforce.com/blogs/2019/06/… – Glen De Marcos Nov 19 '19 at 23:36
  • Chained queueables may be helpful here (in addition to Glen's suggestion) – cropredy Nov 20 '19 at 0:28

Your Answer

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

Browse other questions tagged or ask your own question.