function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
gsappgsapp 

System.AsyncException: Future method cannot be called from a future method

Hi,

 

  I'm having an issue trying to update an account record using a future method.  It is necessary to use the future method because ultimately I want the record to be updated from the result of a webservice method.  From what I understand, callouts are only allowed from future methods.

 

I was following the pattern outlined here.

http://www.cheenath.com/?tutorial/sfdc/sample1/index.html

 

Here Is my code:

 

 

public class setAccount
{
    @future(callout = true)
    public static void setWebsite(String AccountID) 
    {
        //Account a = [SELECT Website from Account where Id =:AccountID];
        Account acc = new Account(Id=AccountID);
        //tempuriOrg.Service1Soap Service = new tempuriOrg.Service1Soap();
        acc.Website = 'http://www.helloworld.com';//Service.HelloWorld();
        update acc;
    }

}

 

trigger CreateTegrityInstances on Account (before update, before insert) 
{
    //setAccount webServiceThing = new setAccount();
    for(Account a : Trigger.new)
    {
        setAccount.setWebsite(a.Id);
        //update a;
    }
}

 

 

 

If I remove the update acc the exception goes away.  

 

Here is the exception:

Update failed. First exception on row 0 with id 001T000000hRmldIAC; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, CreateTegrityInstances: execution of BeforeUpdate caused by: System.AsyncException: Future method cannot be called from a future method

 

 

Any help you can provide is greatly appreciated.

 

Thank you.

Best Answer chosen by Admin (Salesforce Developers) 
metaforcemetaforce

1. the example that you are referring to is using a future method for callout because it's written inside a trigger, and Apex doesn't allow callouts from within a trigger. Any regular Apex class can make an external service callout in a non future method as long as the class is not being invoked from inside a trigger. So identify whether you need to update your account through a trigger only (in which case a future method is a must) or can it be called synchronously from your Apex class?

 

2. Your trigger is written on Account insert/update which is making a future call to update the same account and thus invoking the same trigger again andd thus a future method call. So trigger is being invoked unconditionally resulting in recursive future calls, which Apex doesn't allow. Check if you can invoke setAccount.setWebsite conditionally so that it doesn't become a recursive future call.

 

Drop me a message me if you need any help/suggestion.

All Answers

metaforcemetaforce

1. the example that you are referring to is using a future method for callout because it's written inside a trigger, and Apex doesn't allow callouts from within a trigger. Any regular Apex class can make an external service callout in a non future method as long as the class is not being invoked from inside a trigger. So identify whether you need to update your account through a trigger only (in which case a future method is a must) or can it be called synchronously from your Apex class?

 

2. Your trigger is written on Account insert/update which is making a future call to update the same account and thus invoking the same trigger again andd thus a future method call. So trigger is being invoked unconditionally resulting in recursive future calls, which Apex doesn't allow. Check if you can invoke setAccount.setWebsite conditionally so that it doesn't become a recursive future call.

 

Drop me a message me if you need any help/suggestion.

This was selected as the best answer
sfdcfoxsfdcfox

In addition, your code doesn't support bulk actions (mass edit, import wizard, etc). You should probably pass a list of ID values into the future method, and use a static variable to prevent recursion.

gsappgsapp

Thanks guys.  That makes sense.  I appreciate your time.