Search code examples
powershellvisual-studio-codedebuggingpowershell-7

Configure VSCode's PowerShell extension to show a script stacktrace by default for script-terminating errors


The default output of script-terminating errors that appears in the integrated console of VSCode's PowerShell extension, is not very helpful for debugging. It only shows the error message and the line where the error originated from (in case of module functions, not even the actual line, but just the caller's location).

What I actually want to see is a full script stacktrace in addition to the error message, without having to add exception-handling code to every script.

Example:

Function Test-Me { 
    Test-You
}

Function Test-You {
    throw 'foo error'
}

Test-Me

Actual output:

Exception: C:\Test.ps1:6:2
Line |
   6 |      throw 'foo error'
     |      ~~~~~~~~~~~~~~~~~
     | foo error

Desired output:

Exception: C:\Test.ps1:6:2
Line |
   6 |      throw 'foo error'
     |      ~~~~~~~~~~~~~~~~~
     | foo error

at Test-You, C:\Test.ps1: line 6
at Test-Me, C:\Test.ps1: line 2
at <ScriptBlock>, C:\Test.ps1: line 10
at <ScriptBlock>, <No file>: line 1

While an output like this can be trivially achieved by exception-handling code as follows, it would be too much hassle to add this boilerplate code to each small code snippet I need to debug.

try {
    Test-Me
}
catch {
    $_ | Out-Host
    Write-Debug "`n$($_.ScriptStackTrace)" -Debug
}

While there is a simple way to (also) show a script stacktrace, it causes an error output that is too messy, showing way more information than needed:

# At the top of the script
$ErrorView = 'DetailedView'

Is there a way to configure VSCode's PowerShell extension to produce the desired output?


Solution

  • A simple solution is to add a "launch.json" file. This works well for me, because I keep all my small snippets within a single folder.

    1. Open VSCode from the folder's context menu or launch VSCode normally and open the folder from the File > Open Folder menu item.
    2. Open the Run and Debug tab.
    3. Click on the create a launch.json file link and choose PowerShell, then Launch Current File. This creates a default launch.json file.
    4. Modify the script property to wrap the script call in an exception handler. My customized launch.json looks like this:
      {
          "version": "0.2.0",
          "configurations": [
              {
                  "name": "PowerShell: Launch Current File",
                  "type": "PowerShell",
                  "request": "launch",
                  "script": "try { & ${file} } catch { $_ | Out-Host; Write-Debug -Debug (\"`n\" + $_.ScriptStackTrace) }",
                  "args": []
              }
          ]
      }
      
    5. Save launch.json, it should be automatically saved in a .vscode sub folder.

    After following these steps, every script launched via F5, produces the desired output when a script-terminating error occurs. You can even Ctrl+click on a line of the stacktrace to directly jump to the referred code location.

    VSCode terminal