Can I get detailed exception stacktrace in PowerShell?
Runing such script:
1: function foo()
2: {
3: bar
4: }
5:
6: function bar()
7: {
8: throw "test"
9: }
10:
11: foo
I see
test
At C:\test.ps1:8 char:10
Can I get a detailed stack trace instead?
At bar() in C:\test.ps1:8
At foo() in C:\test.ps1:3
At C:\test.ps1:11
There is a function up on the PowerShell Team blog called Resolve-Error which will get you all kinds of details
Note that $error is an array of all the errors you have encountered in your PSSession. This function will give you details on the last error you encountered.
function Resolve-Error ($ErrorRecord=$Error[0])
{
$ErrorRecord | Format-List * -Force
$ErrorRecord.InvocationInfo |Format-List *
$Exception = $ErrorRecord.Exception
for ($i = 0; $Exception; $i++, ($Exception = $Exception.InnerException))
{ "$i" * 80
$Exception |Format-List * -Force
}
}
Powershell 3.0 adds a ScriptStackTrace property to the ErrorRecord object. I use this function for error reporting:
function Write-Callstack([System.Management.Automation.ErrorRecord]$ErrorRecord=$null, [int]$Skip=1)
{
Write-Host # blank line
if ($ErrorRecord)
{
Write-Host -ForegroundColor Red "$ErrorRecord $($ErrorRecord.InvocationInfo.PositionMessage)"
if ($ErrorRecord.Exception)
{
Write-Host -ForegroundColor Red $ErrorRecord.Exception
}
if ((Get-Member -InputObject $ErrorRecord -Name ScriptStackTrace) -ne $null)
{
#PS 3.0 has a stack trace on the ErrorRecord; if we have it, use it & skip the manual stack trace below
Write-Host -ForegroundColor Red $ErrorRecord.ScriptStackTrace
return
}
}
Get-PSCallStack | Select -Skip $Skip | % {
Write-Host -ForegroundColor Yellow -NoNewLine "! "
Write-Host -ForegroundColor Red $_.Command $_.Location $(if ($_.Arguments.Length -le 80) { $_.Arguments })
}
}
The Skip parameter lets me leave Write-Callstack or any number of error-handling stack frames out of the Get-PSCallstack listing.
Note that if called from a catch block, Get-PSCallstack will miss any frames between the throw site and the catch block. Hence I prefer the PS 3.0 method even though we have fewer details per frame.
There is the automatic variable $StackTrace
but it seems to be a little more specific to internal PS details than actually caring about your script, so that won't be of much help.
There is also Get-PSCallStack
but that's gone as soon as you hit the exception, unfortunately. You could, however, put a Get-PSCallStack
before every throw in your script. That way you get a stack trace immediately before hitting an exception.
I think one could script such functionality by using the debugging and tracing features of Powershell but I doubt it'd be easy.