Debugging Pode
When using Pode there will often be times when you need to debug aspects of your scripts. Debugging in Pode can be achieved in a couple of ways:
- Write messages to the console.
- Use PowerShell's debugger.
Messages
To output messages from your Routes, Timers, etc. you can either call PowerShell's Out-Default
, or Pode's Out-PodeHost
. The latter is just a wrapper around Out-Default
however, it respects the -Quiet
switch if supplied to Start-PodeServer
- suppressing the messages when not needed.
For example, the following will output messages and variables from a Route:
Start-PodeServer {
Add-PodeEndpoint -Address localhost -Port 8080 -Protocol Http
Add-PodeRoute -Method Get -Path '/' -ScriptBlock {
'Start of / Route' | Out-PodeHost
$processes = Get-Process
"Processes found: $($processes.Length)" | Out-PodeHost
$processes[0] | Out-PodeHost
Write-PodeJsonResponse -Value @{ Process = $processes[0] }
}
}
This will output 3 messages to the host window where Pode is running when the Route is invoked, as follows:
Invoke-RestMethod -Uri 'http://localhost:8080/'
Start of / Route
Processes found: 393
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
7 2.45 3.66 3.48 7044 0 AggregatorHost
Tip
You can leave the Out-PodeHost
lines in place, and suppress them by passing -Quiet
to Start-PodeServer
.
Debugger
You can breakpoint directly into a running Pode server by using either PowerShell's Wait-Debugger
or Pode's Wait-PodeDebugger
. The latter is just a wrapper around Wait-Debugger
however, it respects the -EnableBreakpoints
switch if supplied to Start-PodeServer
- allowing you to suppress the breakpoints when not needed. Regardless of the Wait command chosen, the process to attach to the Pode process is the same.
For example, the following will create a breakpoint for PowerShell's debugger when the Route is invoked:
Start-PodeServer -EnableBreakpoints {
Add-PodeEndpoint -Address localhost -Port 8080 -Protocol Http
Add-PodeRoute -Method Get -Path '/' -ScriptBlock {
Wait-PodeDebugger
$processes = Get-Process
Write-PodeJsonResponse -Value @{ Process = $processes[0] }
}
}
The steps to attach to the Pode process are as follows:
-
In a PowerShell console, start the above Pode server. You will see the following output, and you'll need the PID that is shown:
Pode v2.10.0 (PID: 28324) Listening on the following 1 endpoint(s) [1 thread(s)]: - http://localhost:8080/
-
In a browser or a new PowerShell console, invoke the
[GET] http://localhost:8080
Route to hit the breakpoint.Invoke-RestMethod -Uri 'http://localhost:8080/'
-
Open another new PowerShell console, and run the following command to enter the first PowerShell console running Pode - you'll need the PID as well:
Enter-PSHostProcess -Id '<PID_HERE>'
-
Once you have entered the PowerShell console running Pode, run the below command to attach to the breakpoint:
Get-Runspace | Where-Object { $_.Debugger.InBreakpoint } | Select-Object -First 1 | Debug-Runspace -Confirm:$false
- If you used
Wait-PodeDebugger
you'll need to hit thes
key twice to get to the next actual line.
- If you used
-
Hit the
h
key to see the debugger commands you can use. In general, you'll be after:s
: step into the next line, function, scriptv
: step over the next lineo
: step out of the current functiond
: detach from the debugger, and let the script complete
-
You'll also be able to query variables as well, such as
$WebEvent
and other variables you might have created. -
When you are done debugging the current request, hit the
d
key. -
When you're done with debugging altogether, you can exit the entered process as follows:
exit
Toggle Breakpoints
If you're using Wait-PodeDebugger
then you can leave these breakpoint lines in place, and toggle them in non-developer environments by passing -EnableBreakpoints
to Start-PodeServer
. If you don't supply -EnableBreakpoints
, or you explicitly pass -EnableBreakpoints:$false
, then this will disable the breakpoints from being set.
You can also toggle breakpoints via the server.psd1
configuration file:
@{
Server = @{
Debug = @{
Breakpoints = @{
Enable = $true
}
}
}
}
Note
The default state is disabled.
Add-Debugger
You can also use the Add-Debugger script from the PowerShell Gallery, allowing you to debug your Pode server within the same console that started Pode - making the debug process smoother, and not requiring multiple PowerShell consoles.
To install Add-Debugger
, you can do the following:
Install-Script -Name Add-Debugger
Once installed, you'll be able to use the Add-Debugger
command within your Routes/etc., alongside Wait-Debugger
/Wait-PodeDebugger
.
Note
If you're using -EnableBreakpoints
, then setting this to false will not suppress calls to Add-Debugger
.
Start-PodeServer -EnableBreakpoints {
Add-PodeEndpoint -Address localhost -Port 8080 -Protocol Http
Add-PodeRoute -Method Get -Path '/' -ScriptBlock {
Add-Debugger
Wait-PodeDebugger
$processes = Get-Process
Write-PodeJsonResponse -Value @{ Process = $processes[0] }
}
}
The steps to attach to the Pode process are as follows:
-
In a PowerShell console, start the above Pode server.
-
In a browser or a new PowerShell console, invoke the
[GET] http://localhost:8080
Route to hit the breakpoint.Invoke-RestMethod -Uri 'http://localhost:8080/'
-
Back in the PowerShell console running Pode, you'll see that it is now attached to the breakpoint for debugging.
- If you used
Wait-PodeDebugger
you'll need to hit thes
key twice to get to the next actual line.
- If you used
-
Hit the
h
key to see the debugger commands you can use. In general, you'll be after:s
: step into the next line, function, scriptv
: step over the next lineo
: step out of the current functiond
: detach from the debugger, and let the script complete
-
You'll also be able to query variables as well, such as
$WebEvent
and other variables you might have created. -
When you are done debugging the current request, hit the
d
key.
Managing Runspace Names
Internal Runspace Naming
In Pode, internal runspaces are automatically assigned distinct names. This built-in naming convention is crucial for identifying and managing runspaces efficiently, particularly during debugging or when monitoring multiple concurrent processes.
Pode uses specific naming patterns for its internal runspaces, which include:
- Pode_Web_Listener_1
- Pode_Signals_Broadcaster_1
- Pode_Signals_Listener_1
- Pode_Web_KeepAlive_1
- Pode_Files_Watcher_1
- Pode_Main_Logging_1
- Pode_Timers_Scheduler_1
- Pode_Schedules_[Schedule Name]_1 – where
[Schedule Name]
is the name of the schedule. - Pode_Tasks_[Task Name]_1 – where
[Task Name]
is the name of the task.
These default names are automatically assigned by Pode, making it easier to identify the purpose of each runspace during execution.
Customizing Runspace Names
By default, Pode’s Tasks, Schedules, and Timers label their associated runspaces with their own names (as shown above). This simplifies the identification of runspaces when debugging or reviewing logs.
However, if a different runspace name is needed, Pode allows you to customize it. Inside the script block of Add-PodeTask
, Add-PodeSchedule
, or Add-PodeTimer
, you can use the Set-PodeCurrentRunspaceName
cmdlet to assign any custom name you prefer.
Set-PodeCurrentRunspaceName -Name 'Custom Runspace Name'
This cmdlet sets a custom name for the runspace, making it easier to track during execution.
Example
Here’s an example that demonstrates how to set a custom runspace name in a Pode task:
Add-PodeTask -Name 'Test2' -ScriptBlock {
param($value)
# Set a custom name for the current runspace
Set-PodeCurrentRunspaceName -Name 'My Fancy Runspace'
Start-Sleep -Seconds 10
"A $($value) is never late, it arrives exactly when it means to" | Out-Default
}
In this example, the Set-PodeCurrentRunspaceName
cmdlet assigns the custom name 'My Fancy Runspace'
to the task's runspace. This is especially useful for debugging or when examining logs, as the custom name makes the runspace more recognizable.
Retrieving Runspace Names
Pode also provides the Get-PodeCurrentRunspaceName
cmdlet to retrieve the name of the current runspace. This is particularly helpful when you need to log or display the runspace name dynamically during execution.
Get-PodeCurrentRunspaceName
This cmdlet returns the name of the current runspace, allowing for easier tracking and management in complex scenarios with multiple concurrent runspaces.
Example
Here’s an example that uses Get-PodeCurrentRunspaceName
to output the runspace name during the execution of a schedule:
Add-PodeSchedule -Name 'TestSchedule' -Cron '@hourly' -ScriptBlock {
Write-PodeHost "Runspace name: $(Get-PodeCurrentRunspaceName)"
}
In this example, the schedule outputs the name of the runspace executing the script block every hour. This can be useful for logging and monitoring purposes when dealing with multiple schedules or tasks.