[SalesForce] What happens when an exception is thrown within an asynchronous @future method

I have a process builder flow which is triggered by opportunity creation and updates, and that flow executes a bit of apex code. It POSTs to an external service and sets a field on the opportunity:

public class OpportunityProcessor {

  @InvocableMethod
  public static void notifyThirdPartyApi(List<Opportunity> opportunities) {
    for (Opportunity opportunity : opportunities) {

      // make asynchronous http callout
      postToSomeService(opportunity.Id);

      // update opportunity record
      opportunity.Custom_Checkbox__c = true;
      update opportunity;
    }
  }

  @future(callout=true)
  public static void postToSomeService(Id opportunityId) {
    HttpRequest req = new HttpRequest();
    req.setEndpoint('http://service.com/some/resource');
    req.setMethod('POST');
    req.setHeader('Content-Type', 'application/json');
    req.setBody('{"opportunity_id": ' + opportunityId + '}');

    Http http = new Http();

    //
    // What happens to the above method when
    // a System.CalloutException is thrown here? |
    //                     vvvvvvvvvv------------+
    HttpResponse res = http.send(req);
  }
}

What happens if/when that HTTP callout code throws an exception?

Will the opportunity.Custom_Checkbox__c still get updated? Or will the transaction be rolled back?

My intuition says that the transaction will not get rolled back, and the opportunity.Custom_Checkbox__c will stay updated to true. This is because postToSomeService is asynchronously queued for later execution, which means the code in notifyThirdPartyApi will probably be long done by the time the callout code is executed.

But I don't actually know, and I can't find any answers on this page, this page, or this page documenting @future methods.

Best Answer

Your intuition is correct; the future method isn't even called until after the transaction that calls the method has committed. That means the box will be checked, even though the callout may eventually fail. Anything that happens in the future method will have absolutely no impact on the previous transaction.

Related Topic