System.CalloutException: You have uncommitted work pending

I have same exception can please Click Here
The previous post issue is resolved.

Exception: :System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out

Visualforce Page

<apex:page controller="Controller" action="{!init}" showHeader="false" sidebar="false">
    <center>
        <apex:pageBlock title="Request Listener"></apex:pageBlock>          
    </center>
</apex:page>

Controller :

PUBLIC with sharing class Controller
{   
    PUBLIC String fromNumber      = ApexPages.currentPage().getParameters().get('From');
    PUBLIC String toNumber        = ApexPages.currentPage().getParameters().get('To');
    PUBLIC String body            = ApexPages.currentPage().getParameters().get('Body');   
    PUBLIC PageReference init()
    {           
        System.debug('From Phone Number :' +fromNumber);
        System.debug('To phone NUmber :' + toNumber);
        System.debug('Message Body :' + body);

        TwilioRestClient Client = TwilioAPI.getDefaultClient();                                                   
            SYSTEM.DEBUG('FROM AND To  Number is NOT NULL');         
            String formattedNumber='+919876543210';    
            IF(body != NULL)
                body = body;
            ELSE
                body = '';
            Case c = NEW Case (Subject = formattedNumber,Description = body,Origin = 'Phone');
            INSERT c;                 

            Map<String,String> params1 = new Map<String,String>
            {
               'To'   => fromNumber,
               'From' => '+1908280****',
               'Body' => 'Conformation to customer'
            };
            TwilioMessage message = client.getAccount().getMessages().create(params1); /* Valid conformation SMS sent to the Customer.*/                                   
        return null ;
    }
}

While loin as admin then click preview on visualforce page executed but case is not created.I have checked the the debug log it throw the exception.

Answer

You’re trying to insert a new case record and then make the call out — the case is your uncommitted work in this instance.

You should insert the case, and then call a new method which contains the rest of the code for the callout, and mark that with the @future annotation, something like this:

public PageReference init()
{           
    System.debug('From Phone Number :' +fromNumber);
    System.debug('To phone NUmber :' + toNumber);
    System.debug('Message Body :' + body);                                              
    System.debug('FROM AND To  Number is NOT NULL');

    String formattedNumber='+919876543210';    
    if(body != NULL)
        body = body;
    else
        body = '';
    Case c = NEW Case (Subject = formattedNumber,Description = body,Origin = 'Phone');
    insert c;                 

    Map<String,String> params1 = new Map<String,String>
    {
       'To'   => fromNumber,
       'From' => '+1908280****',
       'Body' => 'Conformation to customer'
    };

    DoCallout(params);

    return null ;
}

@future(callout=true)
private static void DoCallout(Map<String, String> params)
{
    TwilioRestClient Client = TwilioAPI.getDefaultClient();

    TwilioMessage message = Client.getAccount().getMessages().create(params);
    // Valid conformation SMS sent to the Customer.                                   
}

Also, you’re doing all of this from the page init method — you really shouldn’t do DML operations on page load as that’s open to abuse and would fail security review if you were submitting this to the AppExchange. It’s much better to have the user confirm they want to perform the action using a button on the page or similar.

Attribution
Source : Link , Question Author : Ramesh S , Answer Author : Daniel Ballinger

Leave a Comment