I have a try/catch/finally approach I use in a lot of my scripts. To ensure I handle scenarios properly I use Write-Error when I encounter certain situations, but, in my error logging block I get the wrong line reference. Here is a sample script to demonstrate the issue:
cls function Show-Error($val) { try { if($val -eq $false) { Write-Error "Line 8" } if($val -eq $true) { Write-Error 'fail' } } catch { "Error in $($_.InvocationInfo.ScriptName)." "--------------------------------------------------" "-- Error information" "--------------------------------------------------" "Line Number: $($_.InvocationInfo.ScriptLineNumber)" "Offset: $($_.InvocationInfo.OffsetInLine)" "Command: $($_.InvocationInfo.MyCommand)" "Line: $($_.InvocationInfo.Line)" "Error Details: $($_)" } finally { "Hey you did something right" } }
Next, I save this function to a .ps1 file and add the function with dot sourcing. To generate errors I run two flavors:
PS C:\powershell\Research\Write-Error> Show-Error $false Show-Error : Line 8 At line:1 char:11 + Show-Error <<<< $false + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Show-Error Hey you did something right
My hope is that the At line value would show me line:8, but instead, it shows me line:1. Alternating this, I run it with $false and I get this
PS C:\powershell\Research\Write-Error> Show-Error $true Show-Error : fail At line:1 char:11 + Show-Error <<<< $true + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Show-Error Hey you did something right
I would hope for this to return Line:11, not line:1. It seems that Write-Error, in this case, escapes from the context of the executing script, so, the value is dereferenced. I tried alternating between throw and Write-Error, but, the same thing happens both ways.
The whole purpose of this exercise is to nail down exactly where a breakdown is occurring in a set of rather large scripts so I can be more precise in my bug tracking. Would either of you genltemen have a way to ensure I get the correct line reference when I break a script?
So... not sure I'm following the logic at all, but... when you use Write-Error, you're generating an error. So you're "moving" the pointer to where the error occurred. I get that you're trying to create a modularized error-showing-thingy, but it won't work. The error needs to be handled entirely within the Catch block, given the way you're doing it.
You might be able to hand off $_.InvocationInfo. Since that's normally done ByRef ByVal, it should create a unique copy of it to work with, meaning subsequent changes wouldn't be reflected in that reference. Guessing. In other words, Show-Error needs to be given all of the information needed, rather than intuiting it from MyInvocation.
Ok. I see what you're getting at. I'll work with the ref approach and see if I can get that going. Thanks for the idea.