I was trying to test if Async opens up a new thread or is tied to the main thread and the result was very interesting.
Consider this class:
public with sharing class TestClassTest {
public static void testFutureException(){
testFuture();
throw new FutureException('Future exception came');
}
@Future
public static void testFuture(){
ARecord__c aRecord = new ARecord__c();
aRecord.Name = 'Test Future';
insert aRecord;
System.debug(aRecord);
}
public class FutureException extends Exception {
}
}
Here I have called a future first and trying to insert a record, and then after that throwing an exception from Main thread, but interestingly the future does not even get called as its not shown in Apex Job
. Even if I put a debug statement inside future job it does not get printed. So My assumption here is, future or any async job waits for the main thread to finish its transaction and then calls the async functions
But even this assumption fails when I do this:
public with sharing class TestClassTest {
public static void testFutureException() {
testDML();
webServiceCallout();
}
public static void webServiceCallout() {
HttpRequest httpRequest = new HttpRequest();
httpRequest.setEndpoint('https://jsonplaceholder.typicode.com/todos/1');
httpRequest.setMethod('GET');
Http http = new Http();
HttpResponse httpResponse = http.send(httpRequest);
System.debug(httpResponse.getBody());
}
@Future
public static void testDML() {
ARecord__c aRecord = new ARecord__c();
aRecord.Name = 'Test Future 1234';
insert aRecord;
}
public class FutureException extends Exception {
}
}
Here I am doing a DML in future, but as per previous assumption, DML should not be executed until my callout is successful. But that is not how it works here. Here it throws an exception saying Error on line 17, column 1: System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out
That means the DML did happen but in Apex Job
I still cant see this future job and neither can I see any debug logs if I put a System.debug
inside future method.
Is there an inbetween layer somewhere between my org instance and Salesforce server where this happens and does not get logged in my org debug logs? And why is future/Queueable or any async process getting affected by the main process/thread?