[SalesForce] Future method cannot be called from a future or batch method, Case Trigger with Salesforce for Social

I get the following inside a Case Trigger when I try to call a future method: System.AsyncException: Future method cannot be called from a future or batch method

So far this exception ONLY occurs when I'm using Salesforce for Social to convert Tweets to Cases (a.k.a. Salesforce for Twitter and Facebook https://appexchange.salesforce.com/listingDetail?listingId=a0N30000003HpEQEA0).

This Case Trigger is working happily with Cases created by Email to Case, by Radian 6 and by manual creation of a Case.

I don't understand what is different about Salesforce for Social that makes this a future method or batch.

How would I write a unit test to recreate this issue?

How should I fix it?

Here is the Trigger code, which is creating Case Routing Requests for routeable Cases, kind of like a promise to send a Case somewhere. The very last line is where the future method is called ( MC_RoutingRequestManager.ProcessRoutingRequests() ):

trigger MC_CaseTrigger on Case (after insert, after update) { 
    Case[] cases = Trigger.new;
    List<CaseRoutingRequest__c> caseRoutingRequestsToInsert = new List<CaseRoutingRequest__c>();

    for(Case c : cases){
        if(c.Routable__c != true)
        {
            continue;
        }

        Case oldCase;

        if (Trigger.isUpdate)
        {
            oldCase = Trigger.oldMap.get(c.Id);

            //if no status change has occurred for this trigger and case has been routed before
            if(oldCase.Status == c.Status && oldCase.Routable__C == true)
            {
                continue;
            }
        }

        List<CaseRoutingRequest__c> existingCaseRoutingRequests = [select id from CaseRoutingRequest__c where Case__c = :c.Id];

        if(existingCaseRoutingRequests.isEmpty())
        {
            CaseRoutingRequest__c request = new CaseRoutingRequest__c();
            request.Case__c = c.Id;
            caseRoutingRequestsToInsert.add(request);
        }
    }

    if(!caseRoutingRequestsToInsert.isEmpty())
    {
        insert caseRoutingRequestsToInsert;
        MC_RoutingRequestManager.ProcessRoutingRequests();
    }
}

Best Answer

Do a check in your trigger for

system.isBatch() || system.isFuture()

and if true then exit trigger