I'm making a call out to get an auth token in the start() method of my batch class (I'm implementing the stateful interface and using a class variable to save this token for the entire batch transaction). Here's a simplified version of my start method.
public Database.QueryLocator start(Database.BatchableContext bc)
{
// Retry for token
Boolean receivedToken = false;
Integer retryCount = 0;
do
{
receivedToken = Helper.getAuthToken();
retryCount++;
}
while (!receivedToken && retryCount <= 3);
if(receivedToken)
{
this.AUTH_TOKEN = Helper.AUTH_TOKEN;
}
else
{
// Returning an empty result
return Database.getQueryLocator('SELECT Id FROM Custom_Object__c WHERE CreatedDate = TOMORROW');
}
return Database.getQueryLocator(this.QUERY);
}
My intention is to avoid the execution of the execute() method when the auth token request fails, but still allow the finish() method to process all of its logic. As you see I'm making a query that I know will return an empty result in all situations and this is working fine, But is this proper the way to do this? I've also posted this comment here which might help someone with a slightly different situation.
I appreciate any suggestions! 🍻
WHERE Id = NULL
. This is likely not massively efficient, of course, but we are async here so that is less of a concern. I would ask why you don't get the token in the constructor and decide to Database.executeBatch or not based on calling a method on the batch instance that itself uses whether or not a token was obtained...? This could be embedded in a method on the batch itself, likemyBatch.executeIfConnected()
...