-errorvariable not working

by jmp8600 at 2013-03-30 12:27:48

Hi there,

i am trying to put below statement after Try construct…
$temp1 = ‘C:\test’
try{
$var = Get-content (Get-ChildItem ".$temp1" -ea stop -ev PathError|where{$.FullName -like "ListofApps"}|select -expand FullName)
.
.
.
.}
Catch
{
write-host $PathError
}

it hits the catch portion if file name containing ListofApp not found but the variable $PathError is empty. I tried putting -ea stop -ev PathError at different places but no luck. How will I be able to capture the exact error in $PathError? is -ev not supported by get-content? I am not seeing that in help get-content -full.

Thx,
-jp
by DonJ at 2013-03-30 12:34:03
The order of the parameters doesn’t matter at all when you’re using named parameters.

-ErrorVariable is a common parameter; PowerShell adds it to every command and to advanced functions. Common parameters are not listed individually in commands’ help; read about_common_parameters for information.

Try running Get-Content -Path nothing.txt -ErrorVariable x -ErrorAction Stop and see if $x contains anything. It does on my computer.
by jmp8600 at 2013-03-30 14:49:51
command you gave me is working but below still not working for me:

Get-content -Path (Get-ChildItem ".\nothing.txt"|where{$
.FullName -like "abc"}|select -expand FullName) -ev x -ea stop

$x is empty
by DonJ at 2013-03-30 15:18:29
Maybe the scoping of the (parentheses). Break it up.


$path = Get-ChildItem ".\nothing.txt"|where{$.FullName -like "abc"}|select -expand FullName
Get-Content -Path $path -ev x -ea stop


? If not, then Get-Content just isn’t running into a trappable exception.
by mjolinor at 2013-03-30 17:18:47
I believe that’s an unhandled exception. Note that

get-content $null -ErrorAction SilentlyContinue


still displays the error.
by mjolinor at 2013-03-30 18:37:25
I’d be careful about relying on error handling routines that rely on ErrorVariable, especially on cmdlets from infrastructure management modules.
I’ve noticed that it just doesn’t work in an Exchange implicit remoting environment.

I suspect that may be a consequence of the "no-language" remoting session. It can’t work there, because the session constraints simply won’t let you create the variable there to store it in.

As infrastructure management gets pushed toward the "cloud", I expect having to work in constrained runspaces to become more common and scripts that rely on ErrorVariable may not port without being re-worked.
by MasterOfTheHat at 2013-04-01 08:43:35
This has to do with the difference in terminating and non-terminating errors, right? ErrorVariable and ErrorAction only come into play on non-terminating errors, and the catch block only works for terminating errors.

Consider this script and the output:
$temp1 = 'c:\temp'
try{
$gcpath = Get-ChildItem -Path $temp1 -ErrorAction Continue -ErrorVariable GCIError |
Where-Object { $
.FullName -like "ListofApps" } |
Select-Object -expand FullName
$var = Get-content -Path $gcpath -ErrorVariable GCError
}
Catch
{
"Caught exception: $"
}
"GCIError: $GCIError"
"GCError: $GCError"
"---------------------------------------------------------------------------------------"
$temp1 = 'c:\temp1'
try{
$gcpath = Get-ChildItem -Path $temp1 -ErrorAction Continue -ErrorVariable GCIError |
Where-Object { $
.FullName -like "ListofApps" } |
Select-Object -expand FullName
$var = Get-content -Path $gcpath -ErrorVariable GCError
}
Catch
{
"Caught exception: $"
}
"GCIError: $GCIError"
"GCError: $GCError"

PS F:\Storage\Scripts\Windows\Junk> .\ev.ps1
Caught exception: Cannot bind argument to parameter ‘Path’ because it is null.
GCIError:
GCError:
---------------------------------------------------------------------------------------
Get-ChildItem : Cannot find path ‘C:\temp1’ because it does not exist.
At F:\Storage\Scripts\Windows\Junk\ev.ps1:17 char:12
+ $gcpath = Get-ChildItem -Path $temp1 -ErrorAction Continue -ErrorVariable GCIEr ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\temp1:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

Caught exception: Cannot bind argument to parameter ‘Path’ because it is null.
GCIError: Cannot find path ‘C:\temp1’ because it does not exist.
GCError:

In the first try/catch block, [list][]gci executes fine because "C:\temp" exists, so no errors, terminating or non-terminating, are encountered[/][]the where-object returns a null value because there are no files in c:\temp like "ListofApps"[/][]that null value is pipelined to Select-Object, which returns a null value[/][]that null is sent to the -Path parameter of the get-content command which causes it to fail with a terminating error[/][]because the script hits a terminating error, it kills the execution of the try block and falls into the catch block[/][*]the $
variable in the catch block is an automatic variable that contains the exception that was caught[/][]After the catch block, you see that the $GCIError variable is empty because no non-terminating errors were encountered in the gci[/][]note that the $GCError variable is empty because no non-terminating errors were encountered in the gc, (even though a terminating error was)[/][/list]

Now, in the second try/catch block, 2 errors are triggered:
[list][
]gci hit a non-terminating error because "C:\temp1" does not exist, and it returns a null value, (we know it was non-terminating because the gc still tries to run)[/][]the where-object again returns a null value because you pipelined a null to it[/][]and the select-object returns a null value because you pipelined a null value to it[/][]that null value is again sent to the -Path parameter of the gc which causes it to fail with a terminating error[/][]that terminating error causes it to fall into the catch block, just like in the first run[/][]now the $_ automatic variable holds the terminating exception from the gc[/][]the GCIError variable holds the non-terminating error from the gci[/][]GCError is still empty because there were no non-terminating errors encountered in the gc[/][/list]

I really hope that is less confusing to read than it was to write…
by mjolinor at 2013-04-01 09:24:06
Actually I think it has to do with the difference between handled exceptions and unhandled exceptions.

Try this:

gc badfile.txt -ev errors
$errors

gc $null -ev errors
$errors


In the first example, the exception is an 'Item not found" exception, and the error was written to $errors.
In the second, the exception is different - ParameterBindingValidationException, and the error is not written to $errors.

In the first example, the parameter binding was successful, and the cmdlet ran but encountered and error trying to open the file, so it wrote it to $errors.
In the second example, the parameter binding failed, so the cmdlet couldn’t even be ran. Writing to ErrorVariable was a parameter of the cmdlet and therefore a function of the cmdlet, but it didn’t run so nothing got written.
by nohandle at 2013-04-02 03:11:32
Mjolinor: I am not sure if I follow what are you saying, IMHO if the exception is handled then you won’t see at all.

AFAIK the main difference is if the exception originates from the commandlet or outside of it. (I am not talking about restricted environments mentioned above).

Here are both terminating and nonterminating exceptions captured in the error variable (EV) (example 1 and 2) and terminating error not capture in example 3:
#Ex: 1
#nonterminating error
gc badfile.txt -ErrorVariable error1 -ErrorAction 'Continue'
$error1

#Ex: 2
Try
{
#terminating error
gc badfile.txt -ErrorVariable error2 -ErrorAction 'Stop'
}
catch
{
"Captured in catch 2:"
$error2
}

#Ex: 3
try
{
#terminating error not originating from the cmdlet
gc $null -ErrorVariable error3 -ErrorAction 'Stop'
}
catch
{
"error3 is empty?:"
$error3 -eq $null
}
by mjolinor at 2013-04-02 06:13:39
"Unhandled" means the cmdlet cannot deal with the error at all - nobody told it what to do if it gets that error.

The Path not found exception is a "handled" error. Whoever wrote the cmdlet put in code to recognize that exception and deal with it. Part of the "handling" is writing the error to ErrorVariable if the parameter is specified. The decision to display the error or not is also part of the handling process, so seeing the error displayed does not neccessarily mean that it was not handled.
by MasterOfTheHat at 2013-04-02 07:01:05
Actually, nohandle, in your examples 1 and 2 above, the error is a non-terminating error, you just told it to stop in the second example. Check the output of that second example:
Captured in catch 2:
Command execution stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop:
Cannot find path ‘F:\Storage\Scripts\Windows\Junk\badfile.txt’ because it does not exist.

The command terminated because the ErrorActionPreference, (ErrorVariable), was set to "Stop"
If you modify your examples 2 and 3 to use the "Continue" ErrorActionPreference, (which is the out-of-the-box default), and included a few output strings, you’ll see that passing a bad file name to gc is a non-terminating error but passing a null value is a terminating error:
"n********* Example 2 **********&quot;<br>Try <br>{<br> gc badfile.txt -ErrorVariable error2 -ErrorAction &#39;Continue&#39;<br> &quot;----- If this line is printed, the error was non-terminating -----&quot;<br>}<br>catch <br>{<br> &quot;===== If this line is printed, the error was terminating =====&quot;<br> $error2<br>}<br>&quot;This is after the try/catch and will show whether or not the ErrorVariable was populated:&quot;<br>$error2<br><br>&quot;n
******** Example 3 *"
Try
{
gc $null -ErrorVariable error3 -ErrorAction 'Continue'
"----- If this line is printed, the error was non-terminating -----"
}
catch
{
"===== If this line is printed, the error was terminating ====="
$error3
}
"This is after the try/catch and will show whether or not the ErrorVariable was populated:"
$error3

Example 2 *
gc : Cannot find path ‘F:\Storage\Scripts\Windows\Junk\badfile.txt’ because it does not exist.
At F:\Storage\Scripts\Windows\Junk\errors.ps1:4 char:2
+ gc badfile.txt -ErrorVariable error2 -ErrorAction ‘Continue’
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (F:\Storage\Scri...unk\badfile.txt:String) [Get-Content], ItemNotFoundEx
ception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

----- If this line is printed, the error was non-terminating -----
This is after the try/catch and will show whether or not the ErrorVariable was populated:
gc : Cannot find path ‘F:\Storage\Scripts\Windows\Junk\badfile.txt’ because it does not exist.
At F:\Storage\Scripts\Windows\Junk\errors.ps1:4 char:2
+ gc badfile.txt -ErrorVariable error2 -ErrorAction ‘Continue’
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (F:\Storage\Scri...unk\badfile.txt:String) [Get-Content], ItemNotFoundEx
ception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand


Example 3 *
===== If this line is printed, the error was terminating =====
gc : Cannot find path ‘F:\Storage\Scripts\Windows\Junk\badfile.txt’ because it does not exist.
At line:3 char:1
+ gc badfile.txt -ErrorVariable error3 -ErrorAction ‘Continue’
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (F:\Storage\Scri...unk\badfile.txt:String) [Get-Content], ItemNotFoundEx
ception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

This is after the try/catch and will show whether or not the ErrorVariable was populated:
gc : Cannot find path ‘F:\Storage\Scripts\Windows\Junk\badfile.txt’ because it does not exist.
At line:3 char:1
+ gc badfile.txt -ErrorVariable error3 -ErrorAction ‘Continue’
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (F:\Storage\Scri...unk\badfile.txt:String) [Get-Content], ItemNotFoundEx
ception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand


And mjolinar makes a valid point: it is entirely up to the programmer which exceptions are handled and which are not handled. Unfortunately, I haven’t had enough coffee and can’t come up with a good explanation of the difference between handled and unhandled exceptions, though.

BTW, mjolinor, I still this is an issue with terminating/non-terminating errors instead of handled/unhandled ones. Just because it is "handled" doesn’t mean it is "non-terminating". The programmer could just as easily made it a terminating error, and they often have good reasons to.
by nohandle at 2013-04-02 07:18:34
[quote="MasterOfTheHat"]Actually, nohandle, in your examples 1 and 2 above, the error is a non-terminating error, you just told it to stop in the second example. [/quote]
Yes I did and hence made it terminating error.

I take mjolinors point as valid it is just this is how i see it:
Unhandled exception : you do not capture (catch) the exception at all or you catch it and mitigate its consequences, but not fully, so you re-throw the exception to notify the upper layers of the program that there has been an error.
Handled: you catch and resolve the exception. You ping computer and it fails, you catch the exception and try again, it works this time. You caught and handled the error.

So if any unhandled error occurs while the cmdlet is doing its job it is automatically written to the $error and errorvariable. At least that is what is seems:
function error
{
[cmdletBinding()]
param()
1/$null
}

Error -errorVariable iFailed

$iFailed
by mjolinor at 2013-04-02 07:29:06
[quote]
BTW, mjolinor, I still this is an issue with terminating/non-terminating errors instead of handled/unhandled ones. Just because it is "handled" doesn’t mean it is "non-terminating". The programmer could just as easily made it a terminating error, and they often have good reasons to.
[/quote]

That is true.

But even if the programmer decided to make it a terminating error, the error handler should have also written the error to ErrorVariable.
That’s part of the error handling process, and it’s not happening.
by nohandle at 2013-04-02 12:16:31
Master of the hat:
This is what I get from your code]
Example 2 *
gc : Cannot find path ‘C:\Users\nohandle\Documents\badfile.txt’ because it does not exist.

At C:\Users\nohandle\AppData\Local\Temp\f338c240-8be9-4460-ad51-59c182aa1347.ps1:4 char:4
+ gc <<<< badfile.txt -ErrorVariable error2 -ErrorAction ‘Continue’
+ CategoryInfo : ObjectNotFound: (C:\Users\nohandle\Documents\badfile.txt:String) [Get-Content], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

----- If this line is printed, the error was non-terminating -----
This is after the try/catch and will show whether or not the ErrorVariable was populated:
gc : Cannot find path ‘C:\Users\nohandle\Documents\badfile.txt’ because it does not exist.

At C:\Users\nohandle\AppData\Local\Temp\f338c240-8be9-4460-ad51-59c182aa1347.ps1:4 char:4
+ gc <<<< badfile.txt -ErrorVariable error2 -ErrorAction ‘Continue’
+ CategoryInfo : ObjectNotFound: (C:\Users\nohandle\Documents\badfile.txt:String) [Get-Content], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand


Example 3 *
===== If this line is printed, the error was terminating =====
This is after the try/catch and will show whether or not the ErrorVariable was populated:[/code]

I don’t see why it should show the error regarding the file ‘badfile.txt’ not found in the example 3 if you specify $null as the path.

What I see is happening is this:
a user uploaded image
What do you think? :))
by MasterOfTheHat at 2013-04-02 12:29:14
Broken image…
by mjolinor at 2013-04-02 13:16:59
[quote]
I don’t see why it should show the error regarding the file ‘badfile.txt’ not found in the example 3 if you specify $null as the path.
[/quote]

That’s what’s still in the variable, left over from Example 2…
by nohandle at 2013-04-02 13:31:26
[quote="mjolinor"]That’s what’s still in the variable, left over from Example 2…[/quote]
In example 2 error2 is used.
In example 3 error3 is used.

So what left overs are you talking about?

The dots were uncalled for… :confused:
by mjolinor at 2013-04-02 13:36:54
Sorry, I missed that. I’ll have a stern word with the dots.

Edit:
I’m not sure what error you’re seeing from example 3. This is from the posted output:

Example 3 *
===== If this line is printed, the error was terminating =====
This is after the try/catch and will show whether or not the ErrorVariable was populated:

Example 3 did not ouput an exception from error3 at all that I can tell.
by MasterOfTheHat at 2013-04-03 06:38:12
[quote="nohandle"]I don’t see why it should show the error regarding the file ‘badfile.txt’ not found in the example 3 if you specify $null as the path.[/quote]
The badfile.txt error was from example 2. Example 3 doesn’t start until the "
Example 3 **********" line. Nothing was output between the "===== if this line is printed…" line and the "This is after the try/catch…" line, so nothing was in the error3 variable.

[quote="nohandle"]
What I see is happening is this:
a user uploaded image
What do you think? ]
Turns out that the url was blocked at work… oh well! I think that, from the example I gave, terminating errors don’t make it to the errorvariable, but non-terminating ones do…

[quote="mjolinor"]I’ll have a stern word with the dots.[/quote]Nice! …