2

Is there any limitations or issues with using Continuations from an embedded visualforce page? I'm attempting to make an asynchronous callout to the Google Calendar API. I have the callout working successfully if done from Javascript remoting or from simply calling the method from the dev console. However, when I break apart the logic into the asynchronous form recommend, my visualforce page rerenders with an Internal Server error and not many other details. In looking at the Google API on the backend, I can see the callout was never made. Below is the async code for reference:

//google calendar initial token request
public Object tokenRequest() {

    String strRequest = 'grant_type='+EncodingUtil.urlEncode('urn:ietf:params:oauth:grant-type:jwt-bearer',
                    'UTF-8')+'&assertion='+EncodingUtil.urlEncode(GoogleCalendarCallOut.tokenBuilder(),'UTF-8');

    // Create continuation with a timeout
    Continuation con = new Continuation(120);
    // Set callback method
    con.continuationMethod='processInitialResponse';

    // Create callout request
    HttpRequest req = GoogleCalendarCallOut.buildInitialRequest();
    system.debug('The request? '+req);

    // Add callout request to continuation
    this.tokenRequestLabel = con.addHttpRequest(req);

    // Return the continuation
    return con;  
}

//callback method for token request
public Object processInitialResponse() {   
    system.debug('Are we ever getting here?');
    // Get the response by using the unique label
    HttpResponse response = Continuation.getResponse(this.tokenRequestLabel);
    // Set the result variable that is displayed on the Visualforce page
    this.tokenResult = response.getBody();
    //parse the response
    Map<String, Object> parsedResponse = (Map<String, Object>) JSON.deserializeUntyped(tokenResult);
    //ok now we have the token, now we need to actually make the request to calendar api to 
    //get the data that we want, the availability
    //parse the token out
    String access_token = (String)parsedResponse.get('access_token');
    system.debug('The access token: '+access_token);

    //create a new continuation for the second callout
    Continuation chainedContinuation = null;


    // Chain continuation if some condition is met
    if (access_token != null) {
        // Create a second continuation 
        chainedContinuation = new Continuation(60);
        // Set callback method
        chainedContinuation.continuationMethod='processMainResponse';

        // Create callout request
        HttpRequest req = GoogleCalendarCallOut.buildMainRequest(access_token, this.userEmailList, 
            this.scheduleDateTime, (Integer)this.l.Last_Timezone_Offset__c);

        // Add callout request to continuation
        this.mainRequestLabel = chainedContinuation.addHttpRequest(req); 
        }

    // Start another continuation 
    return chainedContinuation;
}

//callback method for main request to process the main callout response 
public Object processMainResponse() {

    // Get the response by using the unique label
    HttpResponse mainResponse = Continuation.getResponse(this.mainRequestLabel);

    //parse the response into a map
    Map<String, Object> parsedMainResponse = (Map<String, Object>) JSON.deserializeUntyped(mainResponse.getBody());
    system.debug('Main Response Parsed: '+parsedMainResponse);
    //further parse to just get the calendars (which are the users email addresses)
    system.debug(parsedMainResponse.get('calendars'));

    //ok now we need to loop through all of the calendars and check the busy attribute
    //if the busy array is empty, then it means that person is available and the AR can book time there
    Map<String, Object> parsedCalendars = (Map<String, Object>)parsedMainResponse.get('calendars');
    system.debug('Parsed Calendars: '+parsedCalendars);
    for(String s: parsedCalendars.keySet()) {
        Map<String,Object> busyMap = (Map<String,Object>)parsedCalendars.get(s);
        List<Object> busyCheck = (List<Object>)busyMap.get('busy');
        if(busyCheck.size() == 0) {
            this.availableUsers.add(s);
        }
    }
    system.debug('Specific calendar check: '+parsedCalendars.values());


    return null; //for now
}   
  • Did you check the debug logs? – Salesforcesmarty Feb 6 '17 at 0:30
  • @Salesforcesmarty yes...dev console and chrome dev tools. – George Albrecht Feb 6 '17 at 1:44
  • What did it say? Was the callout invoked at all? You can check it at the bottom of the page of the debug logs Or share the debug log .. – Salesforcesmarty Feb 6 '17 at 2:33
2

There is a known issue when you use Continuation with Visualforce pages re-render action. I am not very sure it is related to it but seems like you have found another way of same problem. Eventually the error message is changed:

Below are two reference links:-

The solution would be creating a case with Salesforce support. They have said it as "NO FIX".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.