We used to get “System.CalloutException: Callout from scheduled Apex not supported” Error when we are making a web service callout from a class which is implementing Database.Schedulable interface because Salesforce does not allow us to make callouts from Schedulable classes.
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);
}
}
}
}
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.
- @future method : A future runs as asynchronously. You can call a future method for executing long-running operations, such as callouts to external Web services or any operation you’d like to run in its own thread, on its own time
Learn more about the 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);
}
}
}
}
Learn about Different types of Exceptions in Salesforce.
Summary
Alternatively, we can also use a Queueable class that implements a database.AllowsCallouts interface to do callouts.
Alternately we can also use a Queueable class that implements Database.AllowsCallouts interface to do callouts.
Yes you are correct.
You can implement Database.AllowsCallouts interface along with Schedulable interface and make callouts from the same class.