Sunday, 6 August 2017

Webservice callout from Scheduled Apex | Report in Batch Job | System.CalloutException: Callout from scheduled Apex not supported


We used to get "System.CalloutException: Callout from scheduled Apex not supported" Error when we are making a webservice callout from a class which is implementing Database.Schedulable interface because Salesforce does not allow us to make callouts from Schedulable classes.

Issue

Sample Scheduler Class


global class SampleScheduler implements Schedulable{
    
    global void execute(SchedulableContext sc) 
    {        
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals');
        request.setMethod('GET');
        HttpResponse response = http.send(request);

        if (response.getStatusCode() == 200) {
            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            List<Object> animals = (List<Object>) results.get('animals');
            System.debug('Received the following animals:');
            for (Object animal: animals) {
                System.debug(animal);
            }
        }
    }    
}

Execute Above Scheduler Class


String sch = '0 00 * * * ?';
system.schedule('Test Schedule', sch, new SampleScheduler());


Error Screen Shot 

Scheduler: failed to execute scheduled job: jobId: 7076A00000EmLPu, class: common.apex.async.AsyncApexJobObject, reason: Callout from scheduled Apex not supported




Solution :- We can solved this issue with below solution.
  1. @future method
Scheduler Class

global class SampleScheduler implements Schedulable{
    
    global void execute(SchedulableContext sc) 
    {        
 
  BatchUtilClass.futureMethodSample();
    }    
}

Future Class Method

public class BatchUtilClass {
    @future(callout=true)
    public static void futureMethodSample() {
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals');
        request.setMethod('GET');
        HttpResponse response = http.send(request);

        if (response.getStatusCode() == 200) {
            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            List<Object> animals = (List<Object>) results.get('animals');
            System.debug('Received the following animals:');
            for (Object animal: animals) {
                System.debug(animal);
            }
        }
    }
}


Thanks
Amit Chaudhary

2 comments:

  1. i want to test this schedulable class and it's not allowing me to do it.

    ReplyDelete
  2. We can also use batch class based on our requirement. Can't we implement the Database.AllowCallouts interface with Schedulable and do the callout from class?

    ReplyDelete