How can I accurately report the line at which an error occurs within a script?

rated by 0 users
This post has 2 Replies | 2 Followers

Top 75 Contributor
Posts 25
willsteele Posted: 05-17-2012 3:54 PM

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?

Top 10 Contributor
Posts 640

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.

Top 75 Contributor
Posts 25

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.

Page 1 of 1 (3 items) | RSS
Copyright 2012 PowerShell.com. All rights reserved.