PowerShellEditorServices icon indicating copy to clipboard operation
PowerShellEditorServices copied to clipboard

Errors thrown when querying for available commands cause no commands to be shown

Open Charles-Gagnon opened this issue 4 years ago • 0 comments

Version : 2021.2.2

This all started when I noticed that the command explorer was blank - never seeming to load the list of available commands.

In the console there was an error like this :

/C:/Users/chgagnon/AppData/Local/Programs/Azure Data Studio - Insiders/resources/app/out/vs/workbench/workbench.desktop.main.js:2759 Error: Internal Error - System.Management.Automation.ParseException: At C:\Users\chgagnon\AppData\Local\Yarn\bin\tsc.ps1:5 char:13
+     *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
+             ~
Unexpected token ')' in expression or statement.

At C:\Users\chgagnon\AppData\Local\Yarn\bin\tsc.ps1:8 char:3
+ if [ -x "$basedir/pwsh" ]; then
+   ~
Missing '(' after 'if' in if statement.

At C:\Users\chgagnon\AppData\Local\Yarn\bin\tsc.ps1:8 char:5
+ if [ -x "$basedir/pwsh" ]; then
+     ~
Missing type name after '['.

At C:\Users\chgagnon\AppData\Local\Yarn\bin\tsc.ps1:9 char:20
+ ... sedir/pwsh"  "$basedir/../Data/global/node_modules/.bin/tsc.ps1" "$@"
+                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unexpected token '"$basedir/../Data/global/node_modules/.bin/tsc.ps1"' in expression or statement.

At C:\Users\chgagnon\AppData\Local\Yarn\bin\tsc.ps1:9 char:72
+ ... sedir/pwsh"  "$basedir/../Data/global/node_modules/.bin/tsc.ps1" "$@"
+                                                                      ~~~~
Unexpected token '"$@"' in expression or statement.
   at System.Management.Automation.ScriptBlock.Create(Parser parser, String fileName, String fileContents)
   at System.Management.Automation.ExternalScriptInfo.ParseScriptContents(Parser parser, String fileName, String fileContents, Nullable`1 definingLanguageMode)
   at System.Management.Automation.ExternalScriptInfo.get_ScriptBlock()
   at System.Management.Automation.ExternalScriptInfo.get_CommandMetadata()
   at System.Management.Automation.CommandInfo.GenerateCommandParameterSetInfo()
   at System.Management.Automation.CommandInfo.get_ParameterSets()
   at Microsoft.PowerShell.EditorServices.Handlers.GetCommandHandler.<Handle>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at OmniSharp.Extensions.LanguageServer.Server.Pipelines.SemanticTokensDeltaPipeline`2.<Handle>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at OmniSharp.Extensions.LanguageServer.Server.Pipelines.ResolveCommandPipeline`2.<Handle>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MediatR.Pipeline.RequestPreProcessorBehavior`2.<Handle>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MediatR.Pipeline.RequestPostProcessorBehavior`2.<Handle>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MediatR.Pipeline.RequestExceptionProcessorBehavior`2.<Handle>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at MediatR.Pipeline.RequestExceptionProcessorBehavior`2.<Handle>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MediatR.Pipeline.RequestExceptionActionProcessorBehavior`2.<Handle>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at MediatR.Pipeline.RequestExceptionActionProcessorBehavior`2.<Handle>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at OmniSharp.Extensions.JsonRpc.RequestRouterBase`1.<<RouteRequest>g__InnerRoute|5_0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at OmniSharp.Extensions.JsonRpc.RequestRouterBase`1.<RouteRequest>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at OmniSharp.Extensions.JsonRpc.InputHandler.<>c__DisplayClass38_0.<<RouteRequest>b__5>d.MoveNext()
	at handleResponse (c:\Users\chgagnon\.azuredatastudio-insiders\extensions\ms-vscode.powershell-2021.2.2\node_modules\vscode-jsonrpc\lib\common\connection.js:477:48)
	at processMessageQueue (c:\Users\chgagnon\.azuredatastudio-insiders\extensions\ms-vscode.powershell-2021.2.2\node_modules\vscode-jsonrpc\lib\common\connection.js:292:17)
	at Immediate.<anonymous> (c:\Users\chgagnon\.azuredatastudio-insiders\extensions\ms-vscode.powershell-2021.2.2\node_modules\vscode-jsonrpc\lib\common\connection.js:276:13)
	at processImmediate (internal/timers.js:456:21)

The important part being here :

   at System.Management.Automation.ScriptBlock.Create(Parser parser, String fileName, String fileContents)
   at System.Management.Automation.ExternalScriptInfo.ParseScriptContents(Parser parser, String fileName, String fileContents, Nullable`1 definingLanguageMode)
   at System.Management.Automation.ExternalScriptInfo.get_ScriptBlock()
   at System.Management.Automation.ExternalScriptInfo.get_CommandMetadata()
   at System.Management.Automation.CommandInfo.GenerateCommandParameterSetInfo()
   at System.Management.Automation.CommandInfo.get_ParameterSets()
   at Microsoft.PowerShell.EditorServices.Handlers.GetCommandHandler.<Handle>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---

This error stack is from the Powershell language service and specifically when it was handling the powershell/getCommand message : https://github.com/PowerShell/PowerShellEditorServices/blob/master/src/PowerShellEditorServices/Services/PowerShellContext/Handlers/GetCommandHandler.cs#L79

The file in question seems to be coming from npm : https://github.com/npm/cmd-shim/blob/master/index.js

And indeed on my system I have a tsc.ps1 file that contains what appears to be a bash script :

#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")

case `uname` in
    *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac

if [ -x "$basedir/pwsh" ]; then
  "$basedir/pwsh"  "$basedir/../Data/global/node_modules/.bin/tsc.ps1" "$@"
  ret=$?
else 
  pwsh  "$basedir/../Data/global/node_modules/.bin/tsc.ps1" "$@"
  ret=$?
fi
exit $ret

(interesting note, I also have a tsc.ps1.ps1 that contains an actual powershell script. So it looks like this might be an issue with how they generate these scripts instead on Windows machines.

Once I removed the scripts in question then everything worked and the command list populated.

Suggested Fix

While it definitely seems like a bug that they're generated this invalid ps1 file I think we should also be catching and ignoring errors that happen while trying to get the metadata from a command. So in this foreach : https://github.com/PowerShell/PowerShellEditorServices/blob/master/src/PowerShellEditorServices/Services/PowerShellContext/Handlers/GetCommandHandler.cs#L61 it we just wrapped the entire inner block in a try/catch then we could just ignore any errors that happen while parsing commands so that a single bad "command" doesn't break the entire feature.

Charles-Gagnon avatar Apr 30 '21 17:04 Charles-Gagnon