forcedotcom / cli

Salesforce CLI
https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/
BSD 3-Clause "New" or "Revised" License
494 stars 78 forks source link

sfdx force:apex:execute does not exit after completion when using inline apex or piping in from command line #667

Closed btamburrino closed 1 year ago

btamburrino commented 4 years ago

Summary

We have a script that runs multiple generated Apex lines and pipes them through sfdx force:apex:execute. This has, historically, worked beautifully, however today when I revisited those scripts, they no longer exit out of sfdx after completing successfully, which blocks the rest of our script execution.

Steps To Reproduce:

Two ways:

OR

Expected result

Anonymous code executes (or returns an error) and then exits back to the command line

Actual result

Anonymous code executes (or returns an error) and hangs, requiring the user to hit CTRL-C to Terminate batch job (Y/N)? - which then terminates the calling shell script that had been blocked.

EDIT Part of this is impatience. It DOES finally exit out after about a minute, however before it was virtually instantaneous.

$ echo "System.debug('Hello');" | sfdx force:apex:execute
Start typing Apex code. Press the Enter key after each line, then press CTRL+D when finished.
System.debug('Hello');
Compiled successfully.
Executed successfully.

49.0 APEX_CODE,DEBUG;APEX_PROFILING,INFO
Execute Anonymous: System.debug('Hello');
13:38:41.32 (32245668)|USER_INFO|[EXTERNAL]|00517000006dgbw|test-pf0yncosurgm@example.com|(GMT-07:00) Pacific Daylight Time (America/Los_Angeles)|GMT-07:00
13:38:41.32 (32302825)|EXECUTION_STARTED
13:38:41.32 (32314888)|CODE_UNIT_STARTED|[EXTERNAL]|execute_anonymous_apex
13:38:41.32 (33034465)|USER_DEBUG|[1]|DEBUG|Hello
13:38:41.33 (33142154)|CUMULATIVE_LIMIT_USAGE
13:38:41.33 (33142154)|LIMIT_USAGE_FOR_NS|(default)|
  Number of SOQL queries: 0 out of 100
  Number of query rows: 0 out of 50000
  Number of SOSL queries: 0 out of 20
  Number of DML statements: 0 out of 150
  Number of DML rows: 0 out of 10000
  Maximum CPU time: 0 out of 10000
  Maximum heap size: 0 out of 6000000
  Number of callouts: 0 out of 100
  Number of Email Invocations: 0 out of 10
  Number of future calls: 0 out of 50
  Number of queueable jobs added to the queue: 0 out of 50
  Number of Mobile Apex push calls: 0 out of 10

13:38:41.33 (33142154)|CUMULATIVE_LIMIT_USAGE_END

13:38:41.32 (33220220)|CODE_UNIT_FINISHED|execute_anonymous_apex
13:38:41.32 (33233918)|EXECUTION_FINISHED

^CTerminate batch job (Y/N)?

Additional information

SFDX CLI Version sfdx-cli/7.75.1-5585088c75 win32-x64 node-v12.18.3

SFDX plugin Version

@oclif/plugin-autocomplete 0.1.5 (core)
@oclif/plugin-commands 1.3.0 (core)
@oclif/plugin-not-found 1.2.4 (core)
@oclif/plugin-plugins 1.9.0 (core)
@oclif/plugin-warn-if-update-available 1.7.0 (core)
@oclif/plugin-which 1.0.3 (core)
@salesforce/lwc-dev-server 2.5.1
├─ @oclif/plugin-help 2.2.3
└─ @oclif/plugin-update 1.3.9
@salesforce/sfdx-plugin-lwc-test 0.1.7
@salesforce/sfdx-trust 3.4.3 (core)
alias 1.1.2 (core)
analytics 1.12.1 (core)
config 1.1.8 (core)
generator 1.1.3 (core)
salesforcedx 49.13.1
├─ templates 49.4.4
├─ custom-metadata 1.0.10
├─ salesforce-alm 49.12.2
└─ apex 0.1.1
sfdx-cli 7.75.1 (core)

OS and version: Windows 10, using primarily Git Bash in Visual Studio Code's Terminal window, but also occurs in normal Command Prompt

btamburrino commented 4 years ago

One of my colleagues on Mac verified that this bug occurs for them as well with the latest sfdx, so it is sadly not a Windows-only issue.

btamburrino commented 4 years ago

The root cause is because of the new timeout in module @salesforce/apex-node executeService.js. In getUserInput() there is a timeout of 60 seconds on the readInterface. This timeout is not closed when the readInterface sends a close event, so the awaiter is waiting for the timeout to complete.

If you add timeout.close(); after resole(apexCode); then the bug reported here goes away. This timeout did not exist in the original implementation that was in salesforce-alm hence why it was not an issue before

// apex-node/../executeService.js getUserInput()
readInterface.on('close', () => {
   resolve(apexCode);
   timeout.close();  // add me!
});
AndrewRayCode commented 3 years ago

A workaround is to write to an intermediate file:

echo "System.debug('Hello');" > throwaway.apex
sfdx force:apex:execute -f throwaway.apex

see also https://github.com/forcedotcom/cli/issues/718

cristiand391 commented 1 year ago

This was fixed a few years ago in apex-node: https://github.com/forcedotcom/salesforcedx-apex/blob/c986abfabee3edf12f396f1d2e43720988fa3911/src/execute/executeService.ts#L97