I'm calling a trigger after insert and after update, which is calling an Apex Class which hits an endpoint. The triggers are working as expected and firing to an endpoint when a checkbox is selected after insert and when a checkbox is updated after update on contact creation.
I'm getting an error in the Apex Jobs > status detail section as follows:
First error: Update failed. First exception on row 0 with id 0035E000013uqdCQAQ; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, LIFT_ContactTrigger: execution of AfterUpdate
caused by: System.AsyncException: Database.executeBatch cannot be called > from a batch start, batch execute, or future method. Trigger.LIFT_ContactTrigger: line 9, column 1
trigger LIFT_ContactTrigger on Contact (after insert, after update) {
list<contact> lstContact = new list<contact> ();
For(Contact c : trigger.new){
if(c.Send_to_Onboarding_Portal__c){
lstContact.add(c);
LIFT_ContactBatchCreation cbc = new LIFT_ContactBatchCreation(lstContact);
id batch = DataBase.executeBatch(cbc,1);
}
}
}
global class LIFT_ContactBatchCreation implements Database.Batchable<sObject>, Database.AllowsCallouts {
private List<Contact> lstContact;
public LIFT_ContactBatchCreation(List<Contact> lsacc) {
System.debug('constructor batch class, ' + lsacc.size());
this.lstContact = lsacc;
}
global Database.QueryLocator start(Database.BatchableContext bc) {
System.debug('start batch class, ' + lstContact.size());
String soqlQuery = 'SELECT Account.Branch_Id__c, Account.Parent_Account_Name__c, Account.Date_became_Customer__c, Account.Go_Live_Date__c, Account.Name, FirstName, LastName, Email, Id From Contact where Id IN :lstContact';
return Database.getQueryLocator(soqlQuery);
}
global void execute(Database.BatchableContext bc, List<Contact> scope){
System.debug('execute batch class, ' + scope.size());
for (Contact contact : scope) {
try {
System.debug(contact.Account.Name);
System.debug(contact.Account.Branch_Id__c);
String accountName = contact.Account.Name;
String branchId = contact.Account.Branch_Id__c;
String firstName = contact.FirstName;
String lastName = contact.LastName;
String email = contact.Email;
Date goLiveDate = contact.Account.Go_Live_Date__c;
Date startDate = contact.Account.Date_became_Customer__c;
String parentAccountName = contact.Account.Parent_Account_Name__c;
//TODO - move to separate class for the callout
Http http = new Http();
HttpRequest request = new HttpRequest();
//TODO - make named credential more generic so can easily be deployed between environments
request.setEndpoint('callout:Glofox_Portal/api/branches/fromSalesforceDemo');
request.setMethod('POST');
request.setHeader('Content-Type', 'application/json;charset=UTF-8');
// Set the body as a JSON object
request.setBody('{"branchId":"'+branchId+'", "parentAccountName":"'+parentAccountName+'", "name":"'+accountName+'", "goLiveDate":"'+goLiveDate+'","startDate":"'+startDate+'" ,"admins":[{"firstName":"'+FirstName+'","lastName":"'+LastName+'","email":"'+email+'"}]}');
HttpResponse response = http.send(request);
System.debug(response.getBody());
// Parse the JSON response
if (response.getStatusCode() != 200) {
//TODO - insert error handling and/or retyr logic here
//TODO - log exception in Salesforce including error code and reason
System.debug('The status code returned was not expected: ' + response.getStatusCode() + ' ' + response.getStatus());
} else {
//TODO - update status field in Salesforce on success and update externalId
System.debug(response.getBody());
}
}
catch (Exception e) {
System.debug('Error-' + e.getMessage());
//Log exception
}
}
update scope;
}
global void finish(Database.BatchableContext bc){
}
}
Any help would be much appreciated.
Thanks