PowerShell Function Stack Traces

This topic contains 3 replies, has 2 voices, and was last updated by  postanote 4 months ago.

  • Author
    Posts
  • #91677

    Mike
    Participant

    Hi,

    I wonder if someone could advise me on what it is that determines whether your modules / scripts throw a PowerShell function stack trace or a .NET module stack trace upon failure.

    I usually try / catch everything and use $PSCmdlet.ThrowTerminatingError($_) in the catch block but the results seem to vary. I have come across a few instances whereby debugging would be much easier with a PowerShell function stack trace. Unfortunately I don't have any code / errors to paste here as this was an intermittent issue with PowerShell direct sessions which I now cannot repro.

    Thanks in advance,

    Mike

  • #91738

    postanote
    Participant

    IIRC, you should always get them on managed code, or so I was taught in several classes a long time ago.
    Modules, scripts, functions, is dependent on what your were doing and how you are trapping for errors.

    So, you have a habit of doing ...

    $error | Format-List -Force

    ... or

    try
    {
    # Your code
    }
    catch [Exception]
    {
    $error | Format-List -Force
    }

    ... or

    try
    {
    # Your code
    }
    catch [Exception]
    {
    echo $_.Exception.GetType().FullName, $_.Exception.Message
    }
    ... or

    function func3
    {
    param ( $startVal )
    trap { write-error $_; Get-Stacktrace }
    1/$startVal
    }

    ... in order to get/see more of the error message data.

    I have not seen an all inclusive resource on your query, but take a look at these articles, as it is the closet I've found to lean toward dealing with the topic you are asking.

    getting a stack trace in PowerShell

    Customizing for errors and traces

    PowerShell: Everything you wanted to know about exceptions

    Error handling is just part of life when it comes to writing code. We can often check and validate conditions for expected behavior. When the unexpected happens, we turn to exception handling. You can easily handle exceptions generated by other people's code or you can generate your own exceptions for others to handle.

    https://kevinmarquette.github.io/2017-04-10-Powershell-exceptions-everything-you-ever-wanted-to-know

    ... and using additional built-in options, for explicitly trapping for errors that you sound like you are already doing.

    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.

    You can also change the default formatting for the error object to include the stack trace. Basically, make your format file by copying the chunk for System.Management.Automation.ErrorRecord from $PSHOME\PowerShellCore.format.ps1xml and add your own element that adds the trace. Then load it with Update-FormatData. For more details, I've just written a blog post about it:

    See also —

    Resolve-Error

    Below is a function that I encourage you to add to your Profile files and then use when reporting an error or ask a question about a exception you are seeing. This function provides all the information we have about the error message making it easier to diagnose what is actually going on.

    It's also been stated that, things may not propagate automatically into the remote sessions. The objects get formatted into strings on the remote side. For stack traces in the remote sessions you'll have to upload this file there and call Update-FormatData there again.

  • #91754

    Mike
    Participant

    Thank you postanote,

    Your detailed answer is much appreciated!

    The key points I will take from this are:

    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.

    ^ Very useful

    It's also been stated that this doesn't things may not propagate automatically into the remote sessions. The objects get formatted into strings on the remote side. For stack traces in the remote sessions you'll have to upload this file there and call Update-FormatData there again.

    ^ This is probably the problem I was facing.

    Cheers,

    Mike

  • #91847

    postanote
    Participant

    No worries.
    Glad it helped.
    ... and now I need to clean up that response as I just noticed a doubled link post.

You must be logged in to reply to this topic.