3

I am trying to run an execute anonymous statement using tooling API. I am running a very simple

System.debug('test');

Now the issue is as this is a GET request, the response that I get is like this -

{"line":-1,"column":-1,"compiled":true,"success":true,"compileProblem":null,"exceptionStackTrace":null,"exceptionMessage":null}

How can I get the results of my code execution to be displayed in my called UI.?

Thanks,

Ray

  • You can deserialize the results into a class and display the individual field / value on the page. – Eric Jul 19 '15 at 14:45
  • I meant it is not giving me the actual result of execution in response. – Kaushik Ray Jul 19 '15 at 18:31
2

The Apex SOAP API is a great choice if want to execute some anonymous Apex and then retrieve the resulting debug log in one API call. You don't need to first create a TraceFlag and then retrieve the resulting debug log in separate API calls.

It's the basis for my blog post Adding Eval() support to Apex.

Here is some sample code for the Apex API executeAnonymous method. The soapSforceCom200608Apex class was generated using the free FuseIT Wsdl2Apex (Disclosure, this is my current employer).

soapSforceCom200608Apex.Apex tooling = new soapSforceCom200608Apex.Apex();

soapSforceCom200608Apex.SessionHeader_element header=new soapSforceCom200608Apex.SessionHeader_element();
tooling.SessionHeader = header;

header.sessionId = UserInfo.getSessionId();
tooling.endpoint_x = URL.getSalesforceBaseUrl().toExternalForm() + '/services/Soap/s/31.0';

tooling.DebuggingHeader = new soapSforceCom200608Apex.DebuggingHeader_element();
//ExecutionLogType - https://www.salesforce.com/us/developer/docs/apexcode/Content/sforce_api_header_debuggingheader.htm
tooling.DebuggingHeader.debugLevel = 'NONE'; 

tooling.DebuggingHeader.categories = new soapSforceCom200608Apex.LogInfo[0];
tooling.DebuggingHeader.categories.add(new soapSforceCom200608Apex.LogInfo());
tooling.DebuggingHeader.categories[0].category = 'Apex_code';
tooling.DebuggingHeader.categories[0].level = 'ERROR';

soapSforceCom200608Apex.ExecuteAnonymousResult result = tooling.executeAnonymous_http('Integer i = 314159; System.debug(LoggingLevel.Error, i);');
System.assert(result.success);
system.debug(result.DebuggingInfo.debugLog);

This outputs to the local debug log:

31.0 APEX_CODE,ERROR
Execute Anonymous: Integer i = 314159; System.debug(LoggingLevel.Error, i);
08:49:24.040 (40971768)|EXECUTION_STARTED
08:49:24.040 (40984194)|CODE_UNIT_STARTED| [EXTERNAL]|execute_anonymous_apex 08:49:24.041 (41651505)|USER_DEBUG|1|ERROR|314159
08:49:24.041 (41697265)|CODE_UNIT_FINISHED|execute_anonymous_apex
08:49:24.042 (42806116)|EXECUTION_FINISHED

  • Hey Daniel..Thanks for the details..I was more inclined towards using REST API callouts here to generate same. Is there a similar REST counterpart that you can help me with ..Thanks a lot..!! – Kaushik Ray Jul 20 '15 at 4:06
  • Only the Tooling API has a REST version of executeAnonymous. However, it requires the use of a TraceFlag and a separate download of the resulting debug log to achieve the same as one call to the Apex API. – Daniel Ballinger Jul 20 '15 at 19:33
1

if you want to see a debug output then you need to get it separately.

With Tooling API it involves:
1. Seting TraceFlag https://developer.salesforce.com/docs/atlas.en-us.api_tooling.meta/api_tooling/tooling_api_objects_traceflag.htm
2. Downloading log file https://developer.salesforce.com/docs/atlas.en-us.api_tooling.meta/api_tooling/tooling_api_objects_apexlog.htm

An example flow can be something like this:
1. Create TraceFlag (this is to tell SFDC to start logging)
2. executeanonymous
3. retrieve debug log
4. delete TraceFlag

step 4 is not strictly necessary but helps keeping things clean.

Also, I am not sure if your use case demands REST specifically and SOAP is a no go, but if you could use SOAP API then you might want to look into SOAP API Developer's Guide.
With Apex SOAP API you do not have to go through as many steps as with Tooling API to get a debug log.
Have a look at the DebuggingHeader documentation: https://developer.salesforce.com/docs/atlas.en-us.196.0.apexcode.meta/apexcode/sforce_api_header_debuggingheader.htm

With Apex API (SOAP version) "executeAnonymous" process looks like so (pseudocode):

val apexCode: String = ...
val conn = getApexConnection
val debugHeader = new DebuggingHeader_element()
debugHeader.setDebugLevel("Debugonly")
conn.__setDebuggingHeader(debugHeader)
val res = conn.executeAnonymous(apexCode)
val log = conn.getDebuggingInfo.getDebugLog
  • Thanks for the details. I will give it a try.!! SOAP is not an option as I want to package it for multiple orgs without the complication of getting WSDL set up. – Kaushik Ray Jul 19 '15 at 14:57
  • If you use Partner WSDL (as opposed to Enterprise one) then it will work for any orgs. – gaiser Jul 19 '15 at 14:58
  • Hey @gaiser, one quick question I can see for downloading log files I need a log id. Is it same as trace id that we get or log id will be from some place else?? Thanks – Kaushik Ray Jul 19 '15 at 19:03
  • Hello @KaushikRay, the Id you get as a result of creating TraceFlag is the one you can use later to delete Trace Flag, but it is not a Log Id. Some operations (e.g. runTestsAsynchronous) return Job Id which you can later use to retrieve specific Log, but executeAnonymous is not one of those. I am not sure if there is a way to get specific Log Id related to executeAnonymous. What you could do is (right after executeAnonymous) query ApexLog (with UserId and Request = 'API') and get last created ApexLog record. This will give you Log Id related to last operation, i.e. executeAnonymous. – gaiser Jul 20 '15 at 9:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.