0

This is my scenario. I have a trigger on a custom object. The trigger invokes a future method in a class. This future method then does a series of callouts using a helper class to update other custom objects in the org.

TriggerA --> FutureMethod --> Helper --> ExternalCallouts

When the FutureMethod creates a request or receives a response it does this via the Helper class. I want to log the raw response of the external callout to a custom object called StoreMyLogs__c

The only inserts / updates I can have are available in the FutureMethod and at that point I have already lost the raw response. It is not possible to do inserts / updates in the Helper class, where the raw response is available.

So I created a static property on the Helper class to accommodate the raw response. This is not working 100% of the times.

So does anyone have any other ideas to log the http response received from the callout?

2
  • Why it is not possible to insert/update in helper class? You have response there right? Sep 20, 2017 at 16:41
  • If you perform a DML Operation in the helper class, the DML operations in the FutureMethod will fail.
    – abhi
    Sep 20, 2017 at 17:33

1 Answer 1

0

Sounds familiar... You can create a Class who's job it is to collect your StoreMyLogs__c records, and eventually commit them to the database.

You can pass your HttpRequest and HttpResponse along to a static list in that Class using a static method immediately after your HTTP.send(request) methods in your future/helper/wherever in the execution context.

Then (here's the tricky bit) just before the return statement in your future Class, call another static method to commit your list of StoreMyLogs__c records...

global class CalloutLogs {

  public static list<StoreMyLogs__c> logEntries {get;set;} //need a static variable to avoid the pending work exception
  static{
    logEntries = new list<StoreMyLogs__c>();              //We want to make sure that we have an instance of the static var
  }

  public static StoreMyLogs__c log(HttpRequest request, HttpResponse response){
    //Converts HttpRequest and HttpResponse to string representations
    //Creates a StoreMyLogs__c record, and adds it to the static list<StoreMyLogs__c> member
    //Returns the StoreMyLogs__c record that was converted
    StoreMyLogs__c returnLog = new StoreMyLogs__c ();
    //marshal your request and response into your StoreMyLogs__c
    //...
    logEntries.add(returnLog);
    return returnLog;
  }

  public static string commitLogs(){
    string returnString = 'Failed to commit StoreMyLogs__c ...';
    if(logEntries != null){
      if(logEntries.size() == 0){
        returnString = 'No StoreMyLogs__c to commit...';
      } else {
        insert logEntries;
        returnString = 'Committed ' + logEntries.size() + ' StoreMyLogs__c  Entries';
      }
    }
    return returnString;
  }
}

THEN: just before you return from your future method... call the commitLogs() method.

system.debug(CalloutLogs.commitLogs());
return; //like the absolute final return!

You just need to make sure that you commit only after ALL callouts have been made to avoid the dreaded "pending work" exception.

3
  • I am going to give this a shot. Thanks for the suggestion.
    – abhi
    Sep 21, 2017 at 12:14
  • I did attempt this, but I am back to You have uncommitted work pending. Please commit or rollback before calling out
    – abhi
    Sep 21, 2017 at 13:35
  • I have accepted your answer. I had to tweak a bit of code on my end to get this going. Thanks once again.
    – abhi
    Sep 21, 2017 at 15:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .